You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@turbine.apache.org by gk...@apache.org on 2024/09/24 14:27:57 UTC

(turbine-core) 02/02: Use released parent v13 and rat version, adapt rat execution and add check goal. Fix NPE in DefaultUserManager. Update to site 2.0 moving xdocs to site/xdoc, fix warning for center tag, add custom configuration from parent and adapt site.xml, fix javadoc

This is an automated email from the ASF dual-hosted git repository.

gk pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/turbine-core.git

commit 82e3d787f80f92f7f28365dbca8c02fa55090f86
Author: gemkall <gk...@apache.org>
AuthorDate: Tue Sep 24 16:22:45 2024 +0200

    Use released parent v13 and rat version, adapt rat execution and add check goal. Fix NPE in DefaultUserManager. Update to site 2.0 moving xdocs to site/xdoc, fix warning for center tag, add custom configuration from parent and adapt site.xml, fix javadoc
---
 pom.xml                                            |  77 +--
 .../turbine/services/BaseInitableBroker.java       |  11 +-
 .../localization/DateTimeFormatterService.java     |   5 +-
 .../org/apache/turbine/services/package-info.java  |   3 +-
 .../schedule/AbstractSchedulerService.java         |   2 +-
 .../services/security/DefaultSecurityService.java  |   2 +-
 .../services/security/DefaultUserManager.java      |  13 +-
 .../org/apache/turbine/util/TurbineConfig.java     |   2 +-
 src/site/site.xml                                  |  51 +-
 src/site/xdoc/changes-pre24.xml                    | 726 +++++++++++++++++++++
 src/site/xdoc/features.xml                         | 117 ++++
 src/site/xdoc/fsd.xml                              | 444 +++++++++++++
 src/site/xdoc/getting-started.xml                  | 124 ++++
 src/site/xdoc/how-to-build.xml                     |  51 ++
 src/site/xdoc/how-to-help.xml                      | 111 ++++
 src/site/xdoc/howto/action-event-howto.xml         | 147 +++++
 src/site/xdoc/howto/annotations.xml                | 177 +++++
 src/site/xdoc/howto/configuration-howto.xml        | 144 ++++
 src/site/xdoc/howto/context-howto.xml              | 472 ++++++++++++++
 src/site/xdoc/howto/extend-user-howto.xml          | 702 ++++++++++++++++++++
 src/site/xdoc/howto/hibernate-howto.xml            | 572 ++++++++++++++++
 src/site/xdoc/howto/ide-vaj-wte-howto.xml          | 149 +++++
 src/site/xdoc/howto/index.xml                      |  57 ++
 src/site/xdoc/howto/intake-howto.xml               | 551 ++++++++++++++++
 src/site/xdoc/howto/jboss-howto.xml                | 127 ++++
 src/site/xdoc/howto/jsp-howto.xml                  |  83 +++
 src/site/xdoc/howto/ldap-howto.xml                 | 189 ++++++
 src/site/xdoc/howto/migrate-from-2_1-howto.xml     | 373 +++++++++++
 src/site/xdoc/howto/migrate-from-2_2-howto.xml     | 294 +++++++++
 src/site/xdoc/howto/migrate-from-2_3-howto.xml     | 117 ++++
 src/site/xdoc/howto/migrate-from-4_0-howto.xml     | 489 ++++++++++++++
 src/site/xdoc/howto/pullmodel-howto.xml            | 138 ++++
 src/site/xdoc/howto/python-howto.xml               | 182 ++++++
 src/site/xdoc/howto/security-howto.xml             | 249 +++++++
 src/site/xdoc/howto/services-howto.xml             | 212 ++++++
 src/site/xdoc/howto/url-mapper-howto.xml           | 256 ++++++++
 src/site/xdoc/howto/url-rewriting-howto.xml        | 187 ++++++
 src/site/xdoc/howto/velocity-site-howto.xml        | 560 ++++++++++++++++
 src/site/xdoc/howto/velocityonlylayout-howto.xml   | 231 +++++++
 {xdocs => src/site/xdoc}/index.xml                 |   4 +-
 src/site/xdoc/j2ee-integration.xml                 | 205 ++++++
 src/site/xdoc/model2+1.xml                         | 125 ++++
 src/site/xdoc/project-map.xml                      | 153 +++++
 src/site/xdoc/proposals.xml                        |  50 ++
 src/site/xdoc/proposals/application-service.xml    | 121 ++++
 .../xdoc/proposals/browser-bound-app-context.xml   | 167 +++++
 src/site/xdoc/proposals/i18n.xml                   |  43 ++
 src/site/xdoc/proposals/naming-service.xml         |  41 ++
 src/site/xdoc/proposals/pp.xml                     |  54 ++
 src/site/xdoc/proposals/resources-service.xml      |  54 ++
 src/site/xdoc/proposals/reusable-components.xml    |  45 ++
 src/site/xdoc/proposals/security-service.xml       | 167 +++++
 src/site/xdoc/proposals/services-framework.xml     |  55 ++
 src/site/xdoc/proposals/services-repository.xml    | 126 ++++
 src/site/xdoc/proposals/unified-templating.xml     | 131 ++++
 src/site/xdoc/pullmodel.xml                        | 153 +++++
 src/site/xdoc/related-projects.xml                 |  46 ++
 src/site/xdoc/services/assemblerbroker-service.xml |  95 +++
 .../xdoc/services/avalon-component-service.xml     | 136 ++++
 src/site/xdoc/services/index.xml                   | 272 ++++++++
 src/site/xdoc/services/jsonrpc-service.xml         | 302 +++++++++
 src/site/xdoc/services/jsp-service.xml             |  95 +++
 src/site/xdoc/services/naming-service.xml          |  95 +++
 src/site/xdoc/services/pull-service.xml            | 233 +++++++
 src/site/xdoc/services/rundata-service.xml         | 452 +++++++++++++
 src/site/xdoc/services/scheduler-service.xml       | 359 ++++++++++
 src/site/xdoc/services/security-service.xml        | 210 ++++++
 src/site/xdoc/services/servlet-service.xml         |  91 +++
 src/site/xdoc/services/session-service.xml         | 135 ++++
 src/site/xdoc/services/template-service.xml        | 254 +++++++
 src/site/xdoc/services/ui-service.xml              | 217 ++++++
 src/site/xdoc/services/uniqueid-service.xml        | 132 ++++
 src/site/xdoc/services/urlmapper-service.xml       |  50 ++
 src/site/xdoc/services/velocity-service.xml        | 112 ++++
 src/site/xdoc/todo.xml                             |  64 ++
 src/site/xdoc/turbine-experiment.xml               | 144 ++++
 src/site/xdoc/turbine-schema.xml                   | 561 ++++++++++++++++
 xdocs/index.xml                                    |   4 +-
 78 files changed, 14072 insertions(+), 78 deletions(-)

diff --git a/pom.xml b/pom.xml
index 9443c5bc..2826c227 100644
--- a/pom.xml
+++ b/pom.xml
@@ -22,7 +22,7 @@
   <parent>
     <groupId>org.apache.turbine</groupId>
     <artifactId>turbine-parent</artifactId>
-    <version>13-SNAPSHOT</version>
+    <version>13</version>
     <relativePath />
   </parent>
   <artifactId>turbine</artifactId>
@@ -532,7 +532,7 @@
         <plugin>
             <groupId>org.apache.rat</groupId>
             <artifactId>apache-rat-plugin</artifactId>
-            <version>0.15</version>
+            <version>${turbine.rat.version}</version>
             <configuration>
                 <excludes>
                   <exclude>xdocs/images/*</exclude>
@@ -875,7 +875,7 @@
         <!-- check the Apache Licence in all source files -->
         <groupId>org.apache.rat</groupId>
         <artifactId>apache-rat-plugin</artifactId>
-        <version>0.15</version>
+        <version>${turbine.rat.version}</version>
       </plugin>
     </plugins>
   </reporting>
@@ -1146,26 +1146,29 @@
       <build>
         <plugins>
           <plugin>
-            <groupId>org.apache.maven.plugins</groupId>
-            <artifactId>maven-site-plugin</artifactId>
+              <groupId>org.apache.maven.plugins</groupId>
+              <artifactId>maven-site-plugin</artifactId>
+              <executions>
+                <execution>
+                  <id>turbine-release-site</id>
+                  <phase>prepare-package</phase>
+                  <goals>
+                    <goal>site</goal>
+                  </goals>
+                </execution>
+              </executions>
+          </plugin>
+          <plugin>
+            <groupId>org.apache.rat</groupId>
+            <artifactId>apache-rat-plugin</artifactId>
             <executions>
               <execution>
-                <id>turbine-release-site</id>
-                <phase>prepare-package</phase>
+                <phase>verify</phase>
                 <goals>
-                  <goal>site</goal>
+                  <goal>check</goal>
                 </goals>
               </execution>
             </executions>
-            <configuration>
-                <reportPlugins>
-                  <reportPlugin>
-                    <groupId>org.apache.rat</groupId>
-                    <artifactId>apache-rat-plugin</artifactId>
-                    <version>0.15</version>
-                  </reportPlugin>
-                </reportPlugins>
-            </configuration>
           </plugin>
           <plugin>
             <!-- build the source and binary distribution packages -->
@@ -1197,6 +1200,14 @@
           </plugin>
         </plugins>
       </build>
+      <reporting>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.rat</groupId>
+            <artifactId>apache-rat-plugin</artifactId>
+          </plugin>
+        </plugins>
+      </reporting>
     </profile>
     <profile>
       <id>docker-testcontainer</id>
@@ -1310,11 +1321,10 @@
        </dependencies>
     </profile>
     <profile>
-      <!-- allow reproducible / verifibable builds: build first and check with 
+    <!-- allow reproducible / verifibable builds: build first and check with
           mvn clean install -Prv-builds
           mvn clean verify artifact:compare -Prv-builds  
-          diffoscope ..
-       -->
+          diffoscope ..   -->
       <id>rv-builds</id>
       <build>
         <plugins>
@@ -1333,32 +1343,10 @@
                 </execution>
                </executions>
           </plugin>
-            <!--  1) to be moved to parent to get buildNumber in parent implemenation.build property 
-                    2) requires no local midifications! 
-             -->
-            <!--plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>buildnumber-maven-plugin</artifactId>
-                <version>3.1.0</version>
-                <executions>
-                  <execution>
-                    <phase>validate</phase>
-                    <goals>
-                      <goal>create</goal>
-                    </goals>
-                  </execution>
-                </executions>
-                <configuration>
-                  <doCheck>true</doCheck>
-                  <doUpdate>true</doUpdate>
-                </configuration>
-            </plugin-->
         </plugins>
       </build>
       <properties>
-          <!-- allow for reproducible builds: should not be inherited but defined in POM for  -->
-          <project.build.outputTimestamp>10</project.build.outputTimestamp>
-          <implementation.build>${scmBranch}@r${buildNumber};noTimeStamp</implementation.build>
+          <!-- outputTimestamp, implementation.build and buildNumber in parent POM  -->
           <scmBranch>trunk</scmBranch>
       </properties>
     </profile>
@@ -1382,8 +1370,7 @@
     <!--jacoco.skip>true</jacoco.skip-->
     <argLine />
   </properties>
-  
-  
+
     <!-- to allow snapshot parents:  https://issues.apache.org/jira/browse/INFRA-15815  jenkins settings.xml is unchanged from beginning -->
     <repositories>
       <repository>
diff --git a/src/java/org/apache/turbine/services/BaseInitableBroker.java b/src/java/org/apache/turbine/services/BaseInitableBroker.java
index 61acbf48..41718d45 100644
--- a/src/java/org/apache/turbine/services/BaseInitableBroker.java
+++ b/src/java/org/apache/turbine/services/BaseInitableBroker.java
@@ -74,11 +74,12 @@ public abstract class BaseInitableBroker
 
     /**
      * Default constructor of InitableBroker.
-     *
+     * <p>
      * This constructor does nothing. Your brokers should be
      * singletons, therefore their constructors should be
      * private. They should also have public YourBroker getInstance()
      * methods.
+     * </p>
      */
     protected BaseInitableBroker()
     {
@@ -161,12 +162,12 @@ public abstract class BaseInitableBroker
 
     /**
      * Provides an instance of Initable class ready to work.
-     *
+     * <p>
      * If the requested class couldn't be instantiated or initialized,
      * an InstantiationException will be thrown. You needn't handle
      * this exception in your code, since it indicates fatal
      * misconfiguration of the system.
-     *
+     * </p>
      * @param className The name of the Initable requested.
      * @return An instance of the requested Initable.
      * @throws InstantiationException if there was a problem
@@ -212,11 +213,11 @@ public abstract class BaseInitableBroker
 
     /**
      * Retrieves an instance of an Initable from the repository.
-     *
+     * <p>
      * If the requested class is not present in the repository, it is
      * instantiated and passed a reference to the broker, saved and
      * then returned.
-     *
+     * </p>
      * @param className The name of the class to be instantiated.
      *
      * @return an instance of the requested class
diff --git a/src/java/org/apache/turbine/services/localization/DateTimeFormatterService.java b/src/java/org/apache/turbine/services/localization/DateTimeFormatterService.java
index 17199e3c..c18fc05d 100644
--- a/src/java/org/apache/turbine/services/localization/DateTimeFormatterService.java
+++ b/src/java/org/apache/turbine/services/localization/DateTimeFormatterService.java
@@ -38,10 +38,11 @@ import org.apache.turbine.util.LocaleUtils;
  * This service is used to format {@link TemporalAccessor} and
  * {@link #map(String, DateTimeFormatter, Locale)} (different flavors)
  * objects into strings.
- *
+ * <p> 
  * The methods may throw {@link java.time.temporal.UnsupportedTemporalTypeException} or
  * {@link DateTimeParseException}, e.g.
  * if the source and the target format do not match appropriately.
+ * </p>
  *
  */
 @TurbineService("DateTimeFormatterService")
@@ -72,7 +73,7 @@ public class DateTimeFormatterService
 
     /**
      * Initialize the service.
-     *
+     * <p> <p> <p> <p>
      * the {@link #dateTimeFormat} from {@link #formatPattern} is initialized with
      * 
      * <ol>
diff --git a/src/java/org/apache/turbine/services/package-info.java b/src/java/org/apache/turbine/services/package-info.java
index f49e2794..09949022 100644
--- a/src/java/org/apache/turbine/services/package-info.java
+++ b/src/java/org/apache/turbine/services/package-info.java
@@ -19,6 +19,7 @@
 
 /**
  * Contains the Service framework for Turbine.
+ * <h1>Turbine services explained</h1>
  * <p>
  * Services are singletons that have pluggable implementation
  * and can participate in Turbine startup and shutdown.
@@ -43,7 +44,7 @@
  * <li> Can execute some action upon system shutdown e.g. close the
  *      opened connections.
  * </ul>
- * <strong>The life cycle of a Service</strong>
+ * <h2>The life cycle of a Service</h2>
  * <p>
  * A Service (or any other Initable, if we had any) is not supposed
  * to do much in it's constructor. Especially it should not allocate
diff --git a/src/java/org/apache/turbine/services/schedule/AbstractSchedulerService.java b/src/java/org/apache/turbine/services/schedule/AbstractSchedulerService.java
index d21af2d6..11935950 100644
--- a/src/java/org/apache/turbine/services/schedule/AbstractSchedulerService.java
+++ b/src/java/org/apache/turbine/services/schedule/AbstractSchedulerService.java
@@ -97,7 +97,7 @@ public abstract class AbstractSchedulerService extends TurbineBaseService implem
 
     /**
      * Shutdowns the service.
-     *
+     * <p>
      * This methods interrupts the housekeeping thread.
      */
     @Override
diff --git a/src/java/org/apache/turbine/services/security/DefaultSecurityService.java b/src/java/org/apache/turbine/services/security/DefaultSecurityService.java
index d6dc658f..7c1e127d 100644
--- a/src/java/org/apache/turbine/services/security/DefaultSecurityService.java
+++ b/src/java/org/apache/turbine/services/security/DefaultSecurityService.java
@@ -52,7 +52,7 @@ import org.apache.turbine.services.TurbineServices;
 
 /**
  * This is a common subset of SecurityService implementation.
- *
+ * <p>
  * Provided functionality includes:
  * <ul>
  * <li> methods for retrieving User objects, that delegates functionality
diff --git a/src/java/org/apache/turbine/services/security/DefaultUserManager.java b/src/java/org/apache/turbine/services/security/DefaultUserManager.java
index c7047a04..32b73dd0 100644
--- a/src/java/org/apache/turbine/services/security/DefaultUserManager.java
+++ b/src/java/org/apache/turbine/services/security/DefaultUserManager.java
@@ -45,7 +45,7 @@ import org.apache.turbine.util.ObjectUtils;
 
 /**
  * Default user manager.
- *
+ * <p>
  * The user manager wraps Fulcrum security user objects into
  * Turbine-specific ones.
  *
@@ -185,9 +185,9 @@ public class DefaultUserManager implements UserManager
 
 	/**
      * Check whether a specified user's account exists.
-     *
+     * <p>
      * The login name is used for looking up the account.
-     *
+     * </p>
      * @param user The user to be checked.
      * @return true if the specified account exists
      * @throws DataBackendException if there was an error accessing the data backend.
@@ -196,10 +196,11 @@ public class DefaultUserManager implements UserManager
     public boolean accountExists(User user)
             throws DataBackendException
     {
-        if (user == null) {
-            return false;
+        boolean result = false;
+        if (user != null) {
+            result = umDelegate.checkExists(user.getUserDelegate());
         }
-        return umDelegate.checkExists(user.getUserDelegate());
+        return result;
     }
 
     /**
diff --git a/src/java/org/apache/turbine/util/TurbineConfig.java b/src/java/org/apache/turbine/util/TurbineConfig.java
index 72f4eff5..7315b283 100644
--- a/src/java/org/apache/turbine/util/TurbineConfig.java
+++ b/src/java/org/apache/turbine/util/TurbineConfig.java
@@ -85,7 +85,7 @@ import org.apache.turbine.annotation.TurbineConfiguration;
  *
  * TODO Make this class enforce the lifecycle contracts
  * 
- * @see https://jakarta.ee/specifications/servlet/6.1/jakarta-servlet-spec-6.1
+ * @see <a href="https://jakarta.ee/specifications/servlet/6.1/jakarta-servlet-spec-6.1">Java Servlet Spec v6.1</a>
  *
  * @author <a href="mailto:quintonm@bellsouth.net">Quinton McCombs</a>
  * @author <a href="mailto:krzewski@e-point.pl">Rafal Krzewski</a>
diff --git a/src/site/site.xml b/src/site/site.xml
index 560a385a..d3f22955 100644
--- a/src/site/site.xml
+++ b/src/site/site.xml
@@ -18,18 +18,23 @@
  under the License.
 -->
 
-<project name="Apache Turbine">
+<site xmlns="http://maven.apache.org/SITE/2.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/SITE/2.0.0 https://maven.apache.org/xsd/site-2.0.0.xsd"
+  name="Apache Turbine" combine.self="merge">  
 
-  <bannerLeft>
-    <name>Apache Turbine</name>
-    <src>/images/turbine-project-apache-separate.png</src>
-    <alt>Apache Turbine</alt>
-    <href>http://turbine.apache.org/</href>
+  <bannerLeft href="https://turbine.apache.org/">
+    <image src="/images/turbine-project-apache-separate.png" alt="Apache Turbine" />
   </bannerLeft>
-  <bannerRight>
-    <src>/images/logo.gif</src>
-  </bannerRight>
-  
+   <bannerRight href="https://turbine.apache.org/">
+        <image src="/images/logo.gif" />
+    </bannerRight>
+  <publishDate format="dd MMMM yyyy" position="left" />
+  <version position="left" />
+  <skin>
+        <groupId>org.apache.maven.skins</groupId>
+        <artifactId>maven-fluido-skin</artifactId>
+        <version>2.0.0-M10</version>
+  </skin>
   <body>
   
      <head>
@@ -39,6 +44,12 @@
       <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">       
        ]]>
     </head>
+    
+    <links>
+        <item name="Apache" href="https://www.apache.org/"> </item>
+        <item name="Turbine" href="https://turbine.apache.org/">  </item>
+          <item name="Fulcrum" href="/fulcrum/"> </item>
+    </links>
   
     <menu name="General Information">
       <item name="Overview"              href="/index.html"/>
@@ -110,10 +121,26 @@
       <item name="How To Help"           href="/how-to-help.html"/>
       <item name="Todo"                  href="/todo.html"/>
     </menu>
+
+    <footer/>
  
       
   </body>
   
-  <!-- custom now configured in parent site -->
+  <!-- custom currently not configured in parent site -->
+  <custom>
+        <fluidoSkin>
+            <topBarEnabled>false</topBarEnabled>
+            <sideBarEnabled>true</sideBarEnabled>
+            <googleSearch>
+                <sitesearch>${project.url}</sitesearch>
+            </googleSearch>
+            <gitHub>
+                <projectId>apache/turbine-build</projectId>
+                <ribbonOrientation>right</ribbonOrientation>
+                <ribbonColor>orange</ribbonColor>
+            </gitHub>
+        </fluidoSkin>
+    </custom>
   
-</project>
+</site>
diff --git a/src/site/xdoc/changes-pre24.xml b/src/site/xdoc/changes-pre24.xml
new file mode 100644
index 00000000..c59b00af
--- /dev/null
+++ b/src/site/xdoc/changes-pre24.xml
@@ -0,0 +1,726 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<document>
+
+<properties>
+  <title>2.x Changes</title>
+</properties>
+
+<body>
+
+<p>
+Latest changes are available from <a href="changes-report.html">Changes Report</a>.
+</p>
+
+<section name="Turbine 2.3">
+
+<p>
+Changes between Turbine 2.2 and 2.3.
+</p>
+
+<subsection name="Building">
+<p>
+  <ul>
+    <li>
+      It is now necessary to use Maven to build Turbine 2.3. The old,
+      ant-based build system is no longer supported and actively removed
+      from the distribution.
+    </li>
+    <li>
+      Turbine requires the Maven Torque plugin to build. If you don't
+      use at least Maven 1.0b9, you will have to install it manually
+      before you can recompile the source code.
+    </li>
+  </ul>
+</p>
+</subsection>
+
+<subsection name="Changes that could break older environments">
+<p>
+  <ul>
+  	<li>
+      The IntakeService has been refactored, introducing two Abstract classes; the
+      DefaultValidator and the NumberValidator. They both contain rules which are
+      applicable to all Validator's and NumbeValidator's respectively. Unnecessary use
+      was being made of (Old) NumberValidator which used BigDecimals, cleaned this up
+      implementing concrete classes for all Number Types. Simplified definition of
+      (number &amp; required) rules in Intake.xml.
+  	</li>
+    <li>
+      The LoginUser action no longer checks to see if the user object is already
+      in the session and returns if it is found.  The user will always be there
+      now.  If you have a custom LoginUser action that still performs this
+      check, you will need to remove it in order for your login action to work.
+    </li>
+    <li>
+      AccessControlList is now an interface and its implementation is in
+      TurbineAccessControlList. This is now configurable and can be replaced
+      by a custom AccessControlList implementation. If older compiled code
+      suddently throws IncompatibleClassChange errors, just recompile and
+      they go away.
+    </li>
+    <li>
+      All deprecated java code was removed (incl. support for webmacro, freemarker
+      and castor). Make sure to not get any deprecation warnings before you
+      switch to 2.3!
+    </li>
+    <li>
+      The LoggingService was removed. Deprecated everything in the utils.Log class.
+    </li>
+    <li>
+       The TurbineResources Service was removed and replaced with commons-configuration.
+    </li>
+    <li>
+       The service initialization code has been changed. This is important if
+       you write services yourself. You should supply a constructor which takes
+       no parameters. The usage of a constructor which takes a RunData object
+       is deprecated and might be removed later. If you're using the supplied
+       services, you shouldn't notice any change.
+    </li>
+    <li>
+       TTWS38: BaseValueParser.getInteger(String name) now returns null if the
+       key name is not found - the old behaviour was to return new Integer(0).
+       For consistency a similar change was made to getBool() and
+       getBigInteger().
+    </li>
+    <li>
+        The velocity mail classes (o.a.t.util.velocity package) now throw
+        VelocityEmailException instead of MessagingException if a problem
+        occurs.
+    </li>
+    <li>
+      The handling of "," as a separator in template names was tightened and
+      clarified. Many places where you could get away with using "/" as a separator
+      or use a leading "/" for a template name now no longer work. There is a long
+      description on how to use and not to use this in the javadoc for
+      org.apache.turbine.services.template.TurbineTemplateService. If you want to volunteer
+      for work on Turbine, feel free to whip this into an xdoc and put it into the
+      documentation tree.
+    </li>
+    <li>
+      Some classes have been moved into different packages to allow cleanup and
+      clarification of their usage. The old locations are still available but
+      deprecated. Examples are the parser classes from org.apache.turbine.util to
+      org.apache.turbine.util.parser and some of the pull tools from org.apache.turbine.util.pull
+      to org.apache.turbine.services.pull.tools
+    </li>
+    <li>
+      getSizeMax() in the UploadService interface and implementations changed
+      from int to long to reflect a change that was made in the underlying
+      commons-fileupload component.
+    </li>
+  </ul>
+</p>
+</subsection>
+
+
+<subsection name="Other changes">
+<p>
+  <ul>
+    <li>
+	 Added ability to specify either the class TurbineResources.properties file
+	 or a new TurbineConfiguration.xml file.  TurbineConfiguration.xml allows
+	 Turbine to pull it's configuration values from multiple locations.  Please
+	 read the howto for more information.
+    </li>
+    <li>
+	 Added a Howto describing using Hibernate with Turbine.  The actual code is
+	 currently not part of the Turbine distrib due to licensing issues, but is very
+	 easy to implement due to Turbine support of Avalon Components.
+    </li>
+    <li>
+	 Changed TurbineUser so that when either perment or temporary values are
+	 stored, if the required hashtable was missing, then it was created.  This
+	 happened in conjunction with the PassiveUserManager.  Additionally, the
+	 setTempStorage(Hashtable newTempStorage) did not actually assign the new
+	 Hashtable.  Cleaned up some of the code so the parallel permanent and temp
+	 data storage methods followed the same patterns.  Created a cactus testcase
+	 to test TurbineUser.
+    </li>
+    <li>
+	 Changed scheduler so that if it is NOT enabled, then it doesn't attempt
+	 to connect to the database and retrieve jobs.  This prevents a spurious
+	 no data source error from showing up in the turbine logs on startup.  Added
+	 a cactus test to test the fix.
+    </li>
+    <li>
+      A new pull tool is available in the session scope called $sessionData.
+      This tool can be used to store data that will persist for the duration
+      of the session.  This should be used instead of the getTemp() and
+      setTemp() methods in TurbineUser.
+    </li>
+    <li>
+      The use of getPerm() and setPerm() methods in Turbine user have been
+      deprecated.  See the Extending Turbine User how-to for using additional
+      database columns for storage if you are using the DBSecurityService.
+      You can also switch to the TorqueSecurityService where it is much easier
+      to use additional columns.
+    </li>
+    <li>
+      Perm scope pull tools have been deprecated.  If you use these type of
+      tools, you need to switch to authorized scope pull tools.  These tools
+      are initialized with a user object.  Any state information that you were
+      storing in the tools itself, you will now need to store in the user
+      object.
+    </li>
+    <li>
+      Turbine used to remove all data from the session before executing
+      the login action.  This no longer happens.  Instead, the session
+      is invalidated before calling to logout action.
+    </li>
+    <li>
+      There is a new pull tool that makes it easy to format
+      Date objects into Strings.  See
+      org.apache.turbine.services.pull.util.DateFormatter for details.
+    </li>
+    <li>
+      Backported the Scheduler service from Fulcrum.  Other Scheduler
+      related changes include:
+      <ul>
+      <li>
+        The scheduler can now be enabled/disabled while Turbine is running.
+      </li>
+      <li>
+        A new pull tool is available to allow access to the Scheduler service
+        from Velocity templates.  See
+        org.apache.turbine.service.scheduler.SchedulerTool for details.
+      </li>
+      <li>
+        TurbineException is now thrown instead of Exception.
+      </li>
+      <li>
+        Torque generated objects are now used to for accessing the database.  You
+        can now add additional fields for the OM objects without modifing the source
+        code.  The OM objects are generated from scheduler-schema.xml
+      </li>
+      <li>
+        updateJob(job) can be used to add a new job.  It will perform the correct
+        action (insert or update) for you.  addJob(job) simply calls updateJob(job).
+      </li>
+      <li>
+        A new fascade class has been created for easier access to the Scheduler Service.
+        It is org.apache.turbine.services.schedule.TurbineScheduler.
+      </li>
+      </ul>
+    </li>
+    <li>
+      Backported the Crypto Service from Fulcrum.
+    </li>
+    <li>
+      TTWS24: With this patch LDAP security services can have users, groups,
+      roles and permissions in the LDAP repository. It also works with users in
+      LDAP and the rest in the Database. <br/>
+      Sample configuration files for Openldap can be found
+      <a href="http://cvs.apache.org/viewcvs/jakarta-turbine-2/conf/openldap/">
+      here</a>
+    </li>
+    <li>
+      TTWS34: Implemented the following functions in LDAPUserManager:
+      store(), createAccount() and removeAccount().
+    </li>
+    <li>
+      added new Logging code which uses commons-logging everywhere.
+    </li>
+    <li>
+       added new Configuration code based on commons-configuration. Switched
+       all configuration requests to commons-configuration.
+       <ul>
+         <li>
+           Configuration values can now be stored in XML, .properties, as well as JNDI Tree.
+         </li>
+         <li>
+		   Configuration values can be overridden.  If you specify JNDI and the .xml, if a value
+		   is found in JNDI, then it is used.  Useful for overriding environment specific values
+		   like mail servers or whether Velocity templates are reloadable.
+         </li>
+       </ul>
+    </li>
+    <li>
+      added Log4j configuration and startup.
+    </li>
+    <li>
+      removed all remaining Torque code.
+    </li>
+    <li>
+      VelocityLayout is now the proposed default layout.
+      VelocityECSLayout might go away post-2.3.
+      See <a href="http://wiki.apache.org/turbine/Turbine2/VelocityOnlyLayout">
+      Moving to VelocityOnlyLayout</a> to see what changes need to be made to your
+      application(s).
+    </li>
+    <li>
+      TurbineException, TurbineRuntimeException, and TurbineError all extend
+      the corresponding "Nestable" exception type from commons-lang.
+    </li>
+    <li>
+      VelocityHtmlMail can now be used in a scheduled job.  It has a new constructor
+      accepting a velocity context object.
+    </li>
+    <li>
+      Intake changes:
+      <ul>
+        <li>
+          Backported changes from Fulcrum version
+        </li>
+        <li>
+          IntakeException is now thrown from intake methods instead of
+          TurbineException and Exception.
+        </li>
+        <li>
+          Multiple XML definition files can be used.
+        </li>
+        <li>
+          Logging has been improved to give more information when an
+          error occurs.
+        </li>
+        <li>
+          The DTD has been updated and fully documented!
+        </li>
+        <li>
+          Intake now uses commons-pool for pooling.
+        </li>
+        <li>
+          intake.dtd is now packaged in the turbine.jar file.  If your
+          intake.xml file validates against
+          jakarta.apache.org/turbine/dtd/intake.dtd, then the DTD included
+          in the jar file will be used instead of the online version.
+        </li>
+        <li>
+          The DTD resolved for intake will now look for intake.dtd on the
+          class path when the DTD in the XMl file is
+          http://jakarta.apache.org/turbine/dtd/intake_2_2_1.dtd.  The application
+          functions in the same way.  This was done to allow XML editors to use
+          the correct version of the DTD.
+        </li>
+        <li>
+          The field object has two new methods to help in creating the HTML
+          input tags for the field.  They are getDisplaySize() and getMaxSize().
+          The display size is set in the xml definition.  The max size is pulled
+          from the maxLength rule (if defined).
+        </li>
+        <li>
+           The setDefaultValue() method on the Field object is now public.  This
+           will allow you to assign a value to a field for display on a form that
+           does come from a mapped object.  Before this change, your only option
+           was to defined the default value in intake.xml.
+          </li>
+      </ul>
+    </li>
+    <li>
+        All deprecated calls to the old org.apache.turbine.util.Log have
+        been replaced with calls to org.apache.commons.logging.Log.
+    </li>
+    <li>
+        A new SessionService has been added.  This will allow access to all
+        sessions in the current context if you use Servlet API 2.3 or better.
+    </li>
+    <li>
+        The non-secure web server for handling xml-rpc requests
+        will now use the services.XmlRpcService.address setting for
+        the address on which to listen for requests.  If the setting
+        is not found in TR.props, it will use the default of 0.0.0.0.
+        This address will cause the server to listen on all
+        addresses of a multi-homed machine.
+    </li>
+    <li>
+        Nearly all of the methods of o.a.t.util.StringUtils has been deprecated.  You should change your
+        application code to use StringUtils from commons-lang.
+    </li>
+    <li>
+        All classed in the org.apache.turbine.util.mail package have been deprecated.  You should change your
+        application code to use commons-mail instead.
+    </li>
+    <li>
+        Turbine now uses commons-fileupload.  The org.apache.turbine.util.upload
+        package has been deprecated.
+    </li>
+    <li>
+        The Pull Service got a new scope: authorized tools. These are like Session Tools but only
+        available after the user logged in.
+    </li>
+    <li>
+        The Pull Service got a new type of tools: RunDataApplicationTools. These tools get the
+        current RunData object passed at every refresh(). This type obviously makes sense only
+        for non-request scope tools.
+    </li>
+    <li>
+      Some services got static facade classes: FactoryService, JspService, RunDataService, SchedulerService.
+    </li>
+    <li>
+      Turbine can use the ConfigurationFactory from commons-configuration to load all kinds of configuration types
+      like XML, JNDI or (still) plain properties files.
+    </li>
+    <li>
+      A completely new URI handling scheme was added and is now the proposed default method to handle URI representations
+      in Turbine. The older URI handling classes like ContentURI and DynamicURI will go after the 2.3 release.
+    </li>
+    <li>
+      A new Security Service is available: TorqueSecurityService. It has the same functionality as the DBSecurityService
+      but allows the usage of arbitrary Torque generated peer classes and objects as security objects.
+    </li>
+    <li>
+      The security object get methods from Security Service have been deprecated and replaced by methods which are
+      able to reference Objects by Name and by Primary Key.
+    </li>
+    <li>
+      The TurbineDB Service has been deprecated. Use Torque and the Component Service to start Torque.
+    </li>
+    <li>
+      It is possible to debug pressure on the PoolService by setting services.PoolService.pool.debug to true
+      in the TurbineResources.properties.
+    </li>
+    <li>
+      Turbine now has some integration for Avalon Components. It can start
+      Avalon based components with the new AvalonComponentService.
+    </li>
+    <li>Added a new TurbineMacros file to the turbine jar, which contains some helper
+        macros for Velocity Templates. Currently there are only some macros to be used
+        with VelocityOnlyLayout to render the page attributes like in VelocityECSLayout
+        based pages.
+    </li>
+    <li>
+      The ComponentService (using the stratum lifecycle interfaces) is
+      deprecated. It will be removed after the 2.3 release as the stratum
+      package is unmaintained. We use the new AvalonComponentService to
+      initialize Torque.
+    </li>
+    <li>
+      ActionEvent and VelocityActionEvent can "ignore" eventSubmit_&lt;xxx&gt; events if they
+      contain an empty or a zero value. This behaviour is controlled by the "action.eventsubmit.needsvalue"
+      property that defaults to "off", which  means no change from the pre-2.3 behaviour. The new behaviour
+      is  useful if you have multiple event fields in a form and only one should be selected
+      (e.g. by a client side java script application).
+    </li>
+    <li>
+      VelocityService now uses the EventCartridge Code to catch and log invocation errors from templates.
+      This is very useful when debugging pull tools, because you get the actual exception in the log and
+      not only the velocity internal stack trace. You can switch this behaviour off by setting
+      "services.VelocityService.catch.errors" to off or false.
+    </li>
+    <li>
+      Intake can now assign "empty" values to fields which are not returned or left out by the browser. This
+      is useful if you want your string fields not to map to null if the user does not enter anything.
+    </li>
+  </ul>
+</p>
+</subsection>
+
+<subsection name="Fixed bugs">
+<p>
+  <ul>
+    <li>
+      TTWS25: Removed deprecated call to TurbineDB
+    </li>
+    <li>
+      TRQD10: Extending Turbine User How-to for T2.2
+    </li>
+    <li>
+      TTWS20: Intake can not set mapped attributes to null.
+    </li>
+    <li>
+      Changed made to scheduled jobs are now recognized by the scheduler
+      service.  Before, it would only recognize changes to the next run
+      time.
+    </li>
+    <li>
+      Fixed null pointer exception during initialization of IntakeTool when there are
+      no groups defined in intake.xml
+    </li>
+    <li>
+      TTWS41: PrimaryKey not set on TurbineUser after insert.
+    </li>
+    <li>
+      Cookies now work properly.  A NullPointerException was being thrown
+      during the call to data.getCookies() if no cookies were present.  Also,
+      the path for cookies was being set incorrectly.  Both of these issues
+      have been fixed.
+    </li>
+    <li>
+      The pull service now really refreshes non-request tool every time a tool is requested.
+    </li>
+  </ul>
+</p>
+</subsection>
+
+</section>
+
+<section name="Turbine 2.2 (= 2.2-rc2)">
+<p>
+Changes between Turbine 2.2-rc1 and 2.2.
+</p>
+
+<subsection name="Other changes">
+<p>
+  <ul>
+    <li>
+      TTWS1: TemplatePageAttributes enhancements
+    </li>
+    <li>
+      TTWS5: Reference support for DynamicURI
+    </li>
+    <li>
+      TTWS13: IntakeTool.getGroups() should be public
+    </li>
+  </ul>
+</p>
+</subsection>
+</section>
+
+<section name="Turbine 2.2-rc1">
+<p>
+Changes between Turbine 2.2-b2 and 2.2-rc1.
+</p>
+
+<subsection name="Other changes">
+<p>
+  <ul>
+    <li>
+      Enhancements to support Apache XML-RPC versions 1.2 alpha 1 and 2.
+    </li>
+  </ul>
+</p>
+</subsection>
+
+<subsection name="Fixed bugs">
+<p>
+  <ul>
+    <li>
+      TRQD2: Update to intake-howto to mention remove()
+    </li>
+  </ul>
+</p>
+</subsection>
+</section>
+
+<section name="Turbine 2.2-b2">
+
+<p>
+Changes between Turbine 2.2-b1 and 2.2-b2.
+</p>
+
+<p>
+<b>The coupled version of Torque has been removed from Turbine 2.2!</b> <br/>
+Get a full list of changes at the
+<a href="http://db.apache.org/torque/changes">Torque-site</a>.
+</p>
+
+<subsection name="Changes that could break older environments">
+<p>
+  <ul>
+    <li>
+      the coupled version of torque has been removed.
+    </li>
+  </ul>
+</p>
+</subsection>
+
+
+<subsection name="Other changes">
+<p>
+  <ul>
+    <li>
+      Maven is used as build system for Turbine 2.2
+    </li>
+    <li>
+      removed antiquated redirect logic.
+    </li>
+    <li>
+      You can use log4j properties directly.
+    </li>
+    <li>
+      The configuration package has been moved from stratum to commons
+    </li>
+    <li>
+      BaseValueParser.setProperty() changed from private to protected
+    </li>
+  </ul>
+</p>
+</subsection>
+
+<subsection name="Fixed bugs">
+<p>
+  <ul>
+    <li>
+      Fixed IllegalStateException when removing an attribute from an invalid
+      session (patch by David Vandegrift - dvandegrift@bluearc.com)
+    </li>
+    <li>
+      Fixed NumberFormatException in UUIdGenerator.
+    </li>
+  </ul>
+</p>
+</subsection>
+</section>
+
+
+<section name="Turbine 2.2b1">
+
+<p>
+Changes between Turbine 2.1 and 2.2b1.
+</p>
+
+<p>
+Torque and Fulcrum (the service framework) have been decoupled in preparation
+for Turbine 3.0. The decoupled versions can be used with Turbine 2.2.
+We strongly recommend to use the decoupled versions (some of the 'old' services
+must be used, because they are used internally by Turbine)
+</p>
+
+<p>
+If you wrote your own services you should also change them to be Fulcrum
+services to make them work with Turbine 3.x
+</p>
+
+<subsection name="Changes that could break older environments">
+
+<p>
+  <ul>
+    <li>
+      The Service interface was extended to allow integration of Service
+      implementations: <br/>
+      <b>Service.getName()</b> <br/>
+      since most Service implementations extend BaseService
+      (which implements a public getName method), this should not be an issue.
+    </li>
+  </ul>
+</p>
+
+</subsection>
+
+
+<subsection name="Other changes">
+
+<p>
+  <ul>
+    <li>
+      <b>ECS, Freemarker and Webmacro</b> services/modules are marked
+      <b>deprecated</b>. You should use Velocity instead.
+    </li>
+    <li>
+      <b>Castor</b> service is marked as <b>deprecated</b>. You should use
+      om/peer classes instead!
+    </li>
+    <li>
+      The XSLT Service is updated to use Xalan 2.0
+    </li>
+    <li>
+      Improved datatype mappings for mysql, oracle, postgresql, sapdb
+    </li>
+    <li>
+      adding support for DB2 on AS400 (patch by Sweaver@rippe.com).
+    </li>
+    <li>
+      adding support for secure connections in the xmlrpc service.
+    </li>
+    <li>
+      Added a configuration parameter to torque, addTimeStamp, that allows the
+      user to generate files without a timestamp. Default is true, timestamps
+      will be generated.
+    </li>
+    <li>
+      Criteria.Criterion implements Serializable
+    </li>
+    <li>
+      DB implements Serializable
+    </li>
+    <li>
+      torque: id-methods <i>sequence</i> and <i>autoincrement</i> are
+      <b>deprecated</b>. You should use <b>native</b>. torque uses the method
+      provided by your database
+    </li>
+    <li>
+      added static strings for ISNULL and ISNOTNULL to Criteria.
+    </li>
+    <li>
+      added getDateString() method to format date fields to DB.
+    </li>
+    <li>
+      added VelocityDirectLayout/Screen to make it possible to embed
+      servlet/JSP outputs into a Velocity template used within Turbine.
+      (patch by raphael.luta@networks.groupvu.com)
+    </li>
+    <li>
+      added an easy to use localization pull tool.
+    </li>
+    <li>
+      Javadocs improvements.
+    </li>
+    <li>
+      Documentation improvements.
+    </li>
+  </ul>
+</p>
+
+</subsection>
+
+
+<subsection name="Fixed bugs">
+
+<p>
+  <ul>
+
+    <li>
+      fixed error in Mssql unique.vm template (removed a blank line)
+    </li>
+    <li>
+      [2301] Embedding message parts in HtmlEmail throws NullPointerException.
+    </li>
+    <li>
+      bugfix for BigDecimal attributes with default value
+    </li>
+    <li>
+      fixed handling of sequences for db2, oracle, postgresql, sapdb
+    </li>
+    <li>
+      fixed syntax for create index (postgresql)
+    </li>
+    <li>
+      fixed problem for postgres with blob style column in TurbineUser table.
+      (patch by Jerome Veryleyen)
+    </li>
+    <li>
+      BaseUnicastRemoteService.java: Corrected method name (setName -> getName).
+    </li>
+    <li>
+      fixed Roleset.add(RoleSet) (patch by lujin@yahoo.com)
+    </li>
+    <li>
+      fixed database - defaultIdMethod (torque)
+    </li>
+    <li>
+      fixed date formating problem with Oracle.
+    </li>
+    <li>
+      fixed problem when ignoreCase was used with ISNULL or ISNOTNULL.
+    </li>
+    <li>
+      fixed Option object initialisation in SelectorBox
+      (patch by Kurt Grafius kurtg@jvoom.com)
+    </li>
+  </ul>
+</p>
+
+</subsection>
+
+</section>
+
+</body>
+</document>
diff --git a/src/site/xdoc/features.xml b/src/site/xdoc/features.xml
new file mode 100644
index 00000000..f1252615
--- /dev/null
+++ b/src/site/xdoc/features.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<document>
+
+ <properties>
+  <title>Turbine Features</title>
+ </properties>
+
+<body>
+
+<section name="Features">
+
+<p>
+This document is for bragging about all of Turbine's features and inherent
+coolness. Turbine is well over 200 classes and contains a boat load of
+features and API's. Many of these can also be used indepently of Turbine.
+Almost all of the default implementations can be easily overridden with
+your own implementations. Turbine also has extensive Javadoc documentation
+for nearly all of the classes as well as in-code comments. It clearly has
+been developed by the people who do web applications on a daily basis and
+have to constantly solve the same problems over and over again.
+</p>
+
+<p>
+<strong>All of these features have been made possible thanks to the over
+30 developers (and growing all the time!) who have <a href="team-list.html">
+contributed</a> to Turbine over the last 10+ years.</strong>
+</p>
+
+<ul>
+    <li>
+      Integration with template systems: Velocity, JSP
+    </li>
+    <li>
+        Utility code for working with Velocity, such as a
+        SelectorBox class for building <code>select</code> boxes</li>
+    <li>
+        Single Entry Point Servlet model for optimal security and control</li>
+    <li>
+        ParameterParsing for GET/POST/PATH_INFO</li>
+    <li>
+        Event based Action handling!</li>
+    <li>
+        Strict MVC guidelines implemented through many interfaces and abstract
+        classes as well as through the template systems.</li>
+    <li>
+        GlobalCache (Singleton based system for caching data across servlets and
+        requests)</li>
+    <li>
+        DateSelector (utility for building the HTML for popup date menus)</li>
+    <li>
+        Generic Services API for creating Singletons</li>
+    <li>
+        <a href="http://www.xml-rpc.com/">XML-RPC</a> Service Integration</li>
+    <li>
+        Localization Services API</li>
+    <li>
+        JNDI Services API</li>
+    <li>
+        Visitor/Member API for managing users</li>
+    <li>
+        Temporary and Permanent storage/management for users session data</li>
+    <li>
+        ACL (Access Control List) based security system that uses Roles and
+        Permissions (and the database schemas)</li>
+    <li>
+        BrowserDetector class for determining which browser someone is using</li>
+    <li>
+        GenerateUniqueId class for getting a unique number (ie: for sessions)</li>
+    <li>
+        Logging via commons-logging, backed by Log4j.
+    </li>
+    <li>
+        A centralized configuration using commons-configuration to make it easy
+        to retrieve properties.
+    </li>
+    <li>
+        Properties can be stored in JNDI, XML, or .properties files!  Properties can
+        override each other.
+    </li>
+    <li>
+        Integration with JavaMail to make sending email painless</li>
+    <li>
+        Integration with JavaMail and Velocity to allow you to send
+        processed Velocity templates as email!</li>
+    <li>
+        Built using Maven</li>
+    <li>
+        Initial application development WAR archive creation tool using Ant</li>
+    <li>
+        Turbine Servlet works cleanly with Servlet API 2.4 and higher</li>
+    <li>
+        Version 5.1 requires JDK 1.8 and higher, Version 5.2 and above requires Java 11 and higher - 100% Pure Java</li>
+</ul>
+
+</section>
+
+</body>
+</document>
diff --git a/src/site/xdoc/fsd.xml b/src/site/xdoc/fsd.xml
new file mode 100644
index 00000000..539b78e9
--- /dev/null
+++ b/src/site/xdoc/fsd.xml
@@ -0,0 +1,444 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<document>
+
+ <properties>
+  <title>Turbine Specification</title>
+ </properties>
+
+<body>
+
+<section name="Specification">
+
+<p>
+Turbine is made up of different modules which serve a specific service within
+the Turbine framework. Five of them are used in the standard configuration.
+In order for the reader to understand the general flow of the Turbine framework,
+each of these modules is explained in detail below.
+</p>
+
+<p style="text-align:center">
+<img src="images/Modules.gif"/>
+</p>
+
+</section>
+
+<section name="The Pipeline">
+
+<p>
+In Turbine 4, the way a request is processed is controlled by the
+<em>Pipeline</em>. This concept has been "borrowed" from the Tomcat
+project. A pipeline consists of <em>Valves</em> which control the single
+processing steps and allow to decide which path the request is to take.
+This allows for extending and adjusting the request processing by adding
+or modifying valves and adding or modifying modules.
+<br />
+Add pipeline schema and link to docs about creating a new module here.
+</p>
+
+<p>
+The default pipeline contains valves to verify session validity, access
+control and login/logout operations.
+</p>
+
+</section>
+
+<section name="Action">
+
+<p>
+The Action module represents a chunk of code that performs a task. For
+example, when a user submits an Html form, one of the hidden fields
+is which Action to execute in order to process the form information.
+The processing generally includes form validation as well as storing
+the form information into a database. The Page is responsible for
+executing the Action before the Screen is executed. That way, the
+Action can help determine which Screen is executed depending on the
+results of the Action.
+</p>
+
+<p>
+The process of the classic pipeline looks like this (somewhat simplified):
+</p>
+
+<table>
+<tr>
+    <td>HTTP Client -></td>
+    <td>Execute Turbine Servlet -></td>
+    <td>Execute Page -></td>
+    <td>Execute Layout/Screen/Navigation -></td>
+    <td>Return Page Content</td>
+</tr>
+<tr>
+    <td></td>
+    <td></td>
+    <td align="center">If Action is defined then...</td>
+    <td></td>
+    <td></td>
+</tr>
+<tr>
+    <td></td>
+    <td></td>
+    <td>Execute Action</td>
+    <td></td>
+    <td></td>
+</tr>
+</table>
+
+<p>
+This model makes it really easy to separate the POST (GET works here as well)
+data processing into component modules that can be re-used. For instance, the
+Action "Logout" can be re-used from a number of different points in the system.
+It performs one single function and performs it well. The advantage of this type
+of behavior is that it prevents you from putting logic for handling form data
+into your servlets. This is great for those of you who want to integrate EJB's
+into Turbine because your Action's can simply make calls to your EJB's to process
+business logic.
+</p>
+
+<p>
+Sometimes it may seem to be difficult to decide which parts of an application
+should go to Actions and which parts go to Pages (or Screens). To help you with
+these decisions, our recommended rules of thumb are
+<ul>
+  <li>
+    Screens <em>show</em> something. That is, they <em>read</em> data, for
+    example a record from a database.
+  </li>
+  <li>
+    Actions <em>do</em> something. That is, they <em>write</em> data, for
+    example from a form to the database.
+  </li>
+  <li>
+    When an Action is finished, it should generally clean up after itself so that
+    a following Screen or other module will find the same state as if no action was
+    performed. In the given example that would mean that the Action writes its data
+    to the database and the Screen would reload it from there.
+  </li>
+</ul>
+</p>
+</section>
+
+<section name="Page">
+
+<p>
+The Page module is the first module in the chain of execution for
+the Page generation. It is considered to be the module which contains
+the rest of the modules (Action, Layout, Screen and Navigation).
+The Page module checks to see if there has been an Action defined in
+the request. If so, it attempts to execute that Action. After the
+Action has been executed, it asks the set Screen object for its Layout.
+Page then attempts to execute the Layout object which the Screen
+returned. Please note that the Action module can modify which Screen
+is executed. Also note that the Screen module has the option to
+override the Layout setting which defaults to "DefaultLayout." (Note:
+the DefaultLayout value is actually defined in the TurbineResources.properties
+file. This way, it is a simple property change instead of having to re-compile
+the Turbine code for your own purposes.
+</p>
+
+</section>
+
+<section name="Screen">
+
+<p>
+The Screen module is essentially considered the "body" of the webpage. The
+Layout module executes the Screen module. This is where the Html of the page is
+generated. <strong>It is entirely possible to call external code here.</strong> For
+example, you can call an EJB to provide you some business data which is then
+transformed using a tool such as <a
+href="http://cocoon.apache.org/">Cocoon</a> to render the business data
+into HTML which is then transfered to the client.
+</p>
+
+</section>
+
+<section name="Navigation">
+
+<p>
+A website generally has a top and bottom navigation scheme. This is generally
+defined as the header and footer of the website. The Navigation is executed by
+the Layout. There may be multiple Navigation modules that the Layout executes
+(ie: the side, top and bottom parts of the page). Since it is generally common
+for multiple webpages to contain the same navigation, it is most common to
+define different Layouts for screens with very different Navigations. The
+advantage of using a system like this is that you can have multiple Navigations
+that are conditionally included and excluded in the Layout. Like Screens, the
+Navigation modules can also call out to external code, such as EJB's to get the
+business logic that is responsible for rendering the Html that is sent to the
+browser.
+</p>
+
+</section>
+
+<section name="Layout">
+
+<p>
+The Layout module is called from the Page module. This modules defines
+the physical Layout of a webpage. It generally defines the location of the
+Navigation portion (ie: the top and bottom part of the webpage) as well as
+the location of where the body (or Screen) of the page is. The
+Layout module executes the Screen module to build the body of the webpage.
+It executes the Navigation modules to build the portions of the webpage
+which define the navigation for the website.
+</p>
+
+<section name="Module object Encapsulation">
+<p style="text-align:center">
+<img src="images/ModuleObjectLayout.gif"/>
+</p>
+
+</section>
+
+<p>
+<dt>From a module object encapsulation point of view, the image above represents
+how each of the modules fits into one another.</dt> For example, the Page module
+executes the Layout module, which then executes the Navigation and Screen
+modules. As one can see, this tends to appear how a templated Html page would
+look. This is no accident, the Turbine framework is essentially an object oriented
+representation of the components of an Html page.
+</p>
+
+</section>
+
+<section name="Loaders">
+
+<p style="text-align:center">
+<img src="images/Loaders.gif"/>
+</p>
+
+<p>
+The loaders are responsible for dynamically loading each of the modules.
+These loaders have an option to cache the module objects in memory for extremely
+fast loading times.
+</p>
+
+<p>
+The loaders use intelligent factories in that we have added a property to
+TurbineResources.properties that allows you to define the "Loader Classpath". In
+other words, it is possible to physically keep all of your web applications
+modules in their own package classpath and the loaders will be responsible for
+finding the right file to execute.
+</p>
+
+<p>
+This feature is great because it allows you to upgrade the core Turbine framework
+without having to make any modifications to your existing code! It also allows
+you to simply distribute your web application as a standalone system and then
+have your users download the Turbine framework as a separate requirement. Then,
+multiple web applications can be combined to form a complete system.
+</p>
+
+<p>
+<strong>Note</strong> that each of the modules must be multithread safe
+since multiple threads may try to execute a single module at the exact same time.
+These rules apply to general servlet programming so they are not that difficult
+to understand. The basic rule is to not try to define any class global variables
+within each of the modules unless it has been wrapped in a synchronized statement.
+</p>
+
+</section>
+
+<section name="Factories">
+<p>
+Each of the loaders mentioned makes use of one or more factories to create the
+different modules.  By default the only factory that is enabled is the Java
+factory that creates requested modules from java class files.
+</p>
+
+<p>
+Factories are required to provide access to an instance of a Loader (see above)
+that is able to load the specific type of module they are responsible for. They
+can in fact implement the Loader themselves. Turbine makes no assumptions about
+a module. The wiring of modules is controlled by the valves of the pipeline
+only.
+</p>
+
+<p>
+You can easily create your own factories by implementing a simple interface
+and registering them in the TurbineResource.properities.  This allows you a lot
+of flexibility in the sense that you can load Turbine modules from <strong>any
+</strong> source that is able to provide you with a java object, for example an
+RMI server or scripting options like Rhino and JPython.  Keep in mind that
+factories <strong>must</strong> be thread-save (the same applies to modules).
+</p>
+
+</section>
+
+<section name="System Flow">
+
+<p>
+When a new request comes in, the Turbine servlet first checks to make sure that
+a ServletAPI HttpSession object exists for the user making the request. If this
+HttpSession object does not exist, a Http redirect header is returned that
+redirects the browser to the "homepage" of the website (by default it is the
+"Login" screen and this can be configured via the TurbineResources.properties
+file). This redirect attempts to set a cookie that is unique for the visitor. If
+the cookie is not accepted, it will not be returned in the new request for the
+"homepage" and thus further session tracking will happen with modified URL's
+that contain the session information within them.
+</p>
+
+<p>
+<strong>Note</strong>: If you do not wish to require the user to login to the
+system with a username and password before executing the pages, then set the
+"Login" screen to be something else. This is done in the Turbine Servlet under
+the data.session.isNew() check. Until the user actually logs in, it is only possible
+to store temporary data for that users session. When the user logs in, it is
+possible to store permant information by simply putting data into a hashtable.
+The implementation of the User object (ie: TurbineUser) in the framework takes care
+of the issues involved with serializing that information to a resource such as a
+database or file on the hard disk.
+</p>
+
+<p>
+After a session with the user has been established, Turbine caches a few frequently
+used pieces of data in the RunData object. This object is created for each and
+every request and is passed around the system in order to provide all of the
+modules with access to request specific information such as a database
+connection, GET/POST/PATH_INFO (GPP) data (via the ParametersParser object), the
+Action and Screen names (made available from the GPP data), and the Document
+object where you put your Html output. The RunData object should never be stored
+in a global context because it is not multithread safe and each of the modules
+is expected to be multithread safe. Also, the RunData object may or may not
+contain information that should be persistent across requests.
+</p>
+
+<p>
+The Turbine servlet then checks to see if a user is attempting to Login to the
+system by looking at the defined Action and checking to see if the value is
+"LoginUser." If so, it will execute the "LoginUser" action (again, the action to
+execute here can be defined in the TurbineResources.properties file). Within this
+action, it is the coders responsibility to define the procedure for
+authenticating the user with the validateUser() method. This will probably mean
+validating the username and password against a database. The abstraction of
+Action modules makes it easily possible to have multiple authentication methods.
+</p>
+
+<p>
+Once the user has been validated (the RunData.save() method has been called) or
+not validated, then the SessionValidator action is executed from within the Turbine
+servlet. The SessionValidator action checks to see if a user has been logged in.
+If the user has not been logged in, then the Screen is set to be the "Login"
+screen. If not, then the users last access datestamp is updated. <strong>If you would
+like to allow the user to view multiple pages without the need to login first,
+you will need to implement your own version of SessionValidator that just
+returns nothing as a result.</strong> Then, for the pages that you will want to make
+secure, you should define a Layout that executes the SessionValidator action to
+make things secure. Then, your Screens should call that "secure" Layout.
+</p>
+
+<p>
+Next, the "DefaultPage" page is executed by the Turbine servlet. The "DefaultPage"
+starts a chain of events that eventually leads to a complete webpage
+development. First, the DefaultPage attempts to see if an Action has been
+defined. If so, then it attempts to execute that Action. See the definition of
+Action and Page above for more information. After the Action has been executed,
+the Screen is then asked for its Layout and the Layout is then executed.
+</p>
+
+<p>
+It is the Layouts responsibility to then execute the Navigation and requested
+Screen. After the Layout has executed its parts, it is finished and control is
+returned to the Turbine servlet which then sends out the page information.
+</p>
+
+</section>
+
+<section name="Access Control Lists and User Permissions">
+
+<p>
+We have provided a beautiful system (because it is so simple and powerful) for
+controlling what a User is allowed to do and not allowed to do. It is based on
+the following concepts:
+</p>
+
+<p>
+One or more Roles are assigned to a User. A Role is a collection of one or more
+Permissions. The AccessControlList uses an AccessControlBuilder that
+allows you to determine whether or not a User has a Permission to do something
+or not.
+</p>
+
+<p>
+Thus, a User can have both the "Admin" and "Guest" Role. Within those Roles are
+the sets of Permissions that are allowed. In the "Admin" Role, one might have
+the Permission, "Edit Users". Then, it is simple to use the AccessControlList to
+check to see if the User has the permission "Edit Users" or if the User has the
+Role "Admin", in which case, it does not matter what the Permissions are.
+</p>
+
+<p>
+You will then use this system within any of modules to determine whether or
+not to execute some code. This will provide you with both a Page level of
+security (does the User have access to this page) as well as a Content level of
+security (does the User have access to see the content on this page, ie:
+hide/show content based on what Permissions the User has).
+</p>
+
+</section>
+
+<section name="Exception Handling">
+
+<p>
+During execution, if at any time an exception is raised, the Turbine servlet
+catches that exception and attempts to execute the "DefaultPage" with the Screen
+set to be "Error". This is a simple debugging screen which displays a java stack
+trace as well as any CGI environment variables that have been set. It is
+possible to modify this Screen to display anything that you wish as well as
+define an alternative error screen within your web application via the
+TurbineResources.properties file. The idea is that all errors can be trapped in one
+location in order to make debugging as simple as possible as well as provide a
+consistent error interface to the users.
+</p>
+
+</section>
+
+<section name="Utility Code">
+
+<p>
+There is a number of utility classes included with Turbine.
+</p>
+
+<p>
+The ParameterParser class takes all of the GET/POST/PATH_INFO data and parses it
+into a hashtable where it can be easily retrieved in a number of forms with the
+provided get* methods. This is how you can have access to form data that has
+been posted by a users web browser.
+</p>
+
+<p>
+The DynamicURI class should be used whenever a URI is needed within the system.
+Each portion of a URI can be defined in order to produce a custom URI that also
+includes the session tracking information if it exists. It is highly recommended
+that you use this class for generating all of your URI's for your application
+because it will allow you to easily add global functionality to your system.
+</p>
+
+<p>
+The DateSelector class generates Html popup menus for month/day/year. The beauty
+of this class is that you can provide a date for it to start with and it will
+automaticially generate the Html popups with that date.
+</p>
+
+</section>
+
+</body>
+</document>
diff --git a/src/site/xdoc/getting-started.xml b/src/site/xdoc/getting-started.xml
new file mode 100644
index 00000000..1ba90834
--- /dev/null
+++ b/src/site/xdoc/getting-started.xml
@@ -0,0 +1,124 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<document>
+
+ <properties>
+  <title>Turbine Getting Started</title>
+ </properties>
+
+<body>
+
+<section name="Getting Started">
+<p>
+The purpose of this document is to define simple documentation on
+getting started with Turbine. For information about the overall
+structure of Turbine, please refer to the <a href="fsd.html">Functional
+Specification Document (FSD)</a> as well as the other documentation that
+is available.
+</p>
+</section>
+
+<section name="Code Organization">
+<p>
+Turbine can be used in two different ways depending on what you need.
+You can choose to only use one way or choose to use both. It is up
+to you.
+</p>
+
+<ul>
+    <li>As a servlet framework with Turbine as the controller.</li>
+    <li>As a framework of useful code in your application.</li>
+</ul>
+
+<p>
+In all cases, it means that you simply link against the API and code
+provided in the turbine.jar file. All you need to do is tell Turbine where its
+configuration file is, add turbine.jar to your classpath and then add
+the appropriate Turbine Java code into your application.
+</p>
+
+<p>
+Turbine is now a fairly large codebase. This can be daunting to people
+who are just starting out with Turbine. However, the code is fairly well
+organized and as you learn about each part of the code, the entire
+architecture starts to make sense and is really quite easy to master.
+All of our code is well javadoc'd so we encourage you to review not only
+the actual source code, but also the documentation. :-) The different
+parts of Turbine are:
+</p>
+
+<ul>
+<li>
+org.apache.turbine.modules - This is where the code for the Modules
+system is stored. The different Modules are described in more detail in
+the <a href="fsd.html">funtional specification document</a>.
+</li>
+<li>
+org.apache.turbine.om - OM stands for Object Model. This is where the
+code that represents Turbine's Security Object Model lives.
+</li>
+<li>
+org.apache.turbine.services - This is where the Services Framework
+lives. The Services framework is a core aspect of Turbine. Essentially
+it is a framework for creating Singleton objects which may also have an
+init() and destroy() lifecycle. There are Services for many different
+things.
+</li>
+<li>
+org.apache.turbine.util - The Util package is just that. A package of
+utility code that is used within Turbine. There is code that will allow
+you to easily send template based email using Velocity as
+well as many other commonly used web application tools.
+</li>
+</ul>
+</section>
+
+<section name="Standalone Usage">
+<p>
+Turbine can be easily used on its own. In order to do so, all you need
+to do is something like this before you attempt to make a call to Turbine
+based code:
+</p>
+
+<source>
+TurbineConfig tc = new TurbineConfig("/path","TurbineResources.properties");
+tc.init();
+</source>
+
+<p>
+What that does is it tells Turbine the path to its configuration file
+based on the relative path from "/path" (insert your own path). This is
+held as a static in memory and therefore you only need to do it once.
+You do not even have to worry about hanging on to the TurbineConfig
+object. For more information, please see the javadoc for the
+TurbineConfig object.
+</p>
+</section>
+
+<section name="Further Questions and Comments">
+<p>
+If you have further questions or comments, please send them to the <a
+href="mail-lists.html">Turbine Mailing lists</a>.
+</p>
+</section>
+
+</body>
+</document>
diff --git a/src/site/xdoc/how-to-build.xml b/src/site/xdoc/how-to-build.xml
new file mode 100644
index 00000000..220f93e4
--- /dev/null
+++ b/src/site/xdoc/how-to-build.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<document>
+
+ <properties>
+  <title>How To Build Turbine</title>
+ </properties>
+
+<body>
+
+<section name="How to build Turbine">
+
+<p>
+  First, check Java version is Java 11 or above.
+</p>
+<p>
+  Turbine is built using the <a href="http://maven.apache.org/">Maven</a> build
+  tool.  So to get started you should download and install Maven.
+</p>
+
+<p>
+  To build Turbine, from the Turbine home directory just run <code>mvn install</code> the
+  project will be compiled, test cases run, and jar files created.
+  This will also install the artifact into your local Maven repository as well.
+</p>
+<p>
+  To build the site documentation, run <code>mvn site</code>, and this will build
+  the site documentation for the project.
+</p>
+
+</section>
+</body>
+</document>
diff --git a/src/site/xdoc/how-to-help.xml b/src/site/xdoc/how-to-help.xml
new file mode 100644
index 00000000..bad2bfd6
--- /dev/null
+++ b/src/site/xdoc/how-to-help.xml
@@ -0,0 +1,111 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<document>
+
+ <properties>
+  <title>How To Help with Turbine Development</title>
+ </properties>
+
+<body>
+
+<section name="How to help">
+
+<p>
+  If you are a new developer to Turbine or even an existing developer, these are
+  areas where you can take ownership and help complete. Please do not ask us how
+  you can help, but rather specific questions about how you think that these items
+  should be implemented. It is up to you to take initiative and provide solutions
+  to the missing functionality described below. ;-)
+</p>
+
+<p>
+  It is always possible to take ownership of any portion of the project. The way
+  to do this is to post a message to the turbine-developer mailing list.  Just explain
+  what you are wanting to work on or any ideas that you might have on the subject.
+</p>
+
+<p>
+    Documentation is <b>*always*</b> appreciated in any form.  The documentation for
+    Turbine exists in basically four forms.
+    <ul>
+        <li>
+            XML formatted docs (xdoc) - This is used to generate the documentation
+            on the jakarta site.  The source for this documentation can be found
+            in the xdocs directory in the source distribution.  To submit additional
+            documentation in this form or patches to existing documentation, please
+            create an issue is the
+            <a href="https://issues.apache.org/jira/browse/TRB">issue tracking system</a>
+            and attach the patch files (or new files).
+        </li>
+        <li>
+            Mailing list - The archives of <a href="https://lists.apache.org/list.html?user@turbine.apache.org">user@turbine.apache.org</a> and
+            <a href="https://lists.apache.org/list.html?dev@turbine.apache.org">dev@turbine.apache.org</a> are an excellent source of information
+            for the project. Answering questions that are asked on the mailing list
+            or simply posting information that might be of use to other Turbine users
+            would be very welcome contribution to the project.
+        </li>
+        <li>
+            The <a href="http://wiki.apache.org/turbine/">Turbine
+            Wiki</a> another repository of documentation for the project.  It
+            contains development information, user documentation, how-to documents,
+            discussion of new features, etc.  Anyone can add new pages and edit existing
+            pages very easily!  This is perhaps the easiest way to contribute documentation
+            (well, second only to the mailing lists).
+        </li>
+        <li>
+            The javadocs are another very important form of documentation for the project.
+            Changes to this form of documentation should be in the form of patches.  To submit
+            them, create a new issue in the
+            <a href="https://issues.apache.org/jira/browse/TRB">issue tracking system</a>
+            and attach your patch(es) or open in github an Pull Request (PR).
+        </li>
+    </ul>
+    The documentation is probably the easiest area for anyone to contribute in.  If you are
+    new to Turbine and learning your way around, documenting what you learn and submitting
+    it in any other the various forms would be appreciated.
+</p>
+
+<p>
+    Testing is another area in which help is always needed.  This could consist of simply
+    reporting problems that you run into using Turbine.  It could also consist of submitting
+    code to perform unit tests.  Turbine uses JUnit and Cactus for testing.  You can find
+    examples in the src/test directory of the source distribution.
+</p>
+
+<p>
+    If you do discover a defect in the Turbine product, please create a defect issue in
+    the <a href="https://issues.apache.org/jira/browse/TRB">issue tracking system</a> clearly
+    describing the problem.  If you can take the time to track down the source of the problem,
+    it would certainly help speed the process of getting it corrected.  Of course, actually
+    fixing the problem and attaching a patch to the issue would be greatly appreciated.
+</p>
+
+<p>
+    You can also contribute to the project by enhancing existing functionality and/or
+    adding new functionality.  There is a current list of requested features on the
+    <a href="http://wiki.apache.org/turbine/Turbine2/WishList">Turbine Wiki</a>.  Everyone is encouraged to take part in the discussion, design, and
+    implementation.
+</p>
+
+</section>
+
+</body>
+</document>
diff --git a/src/site/xdoc/howto/action-event-howto.xml b/src/site/xdoc/howto/action-event-howto.xml
new file mode 100644
index 00000000..2b8dc3c3
--- /dev/null
+++ b/src/site/xdoc/howto/action-event-howto.xml
@@ -0,0 +1,147 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<document>
+
+ <properties>
+  <title>Action Events Howto</title>
+ </properties>
+
+<body>
+
+<section name="Action Events">
+
+<p>
+Turbine has a very useful feature that makes handling form submission
+much more painless for the developer. In order to understand this, you
+need to be familiar with the way that Turbine handles Actions. What happens
+is that when a URI has the action= variable defined, a class is executed
+before all of your other Screen classes by your Page class. So, consider
+the following URI (I'm using the
+<a href="velocity-site-howto.html">VelocitySite Howto</a> example):
+</p>
+
+<p>
+<code>http://www.server.com/servlet/Turbine/template/AddUser/action/NewUser</code>
+What happens is that Turbine will first execute the Java class file Action
+named NewUser. Then, any class that extends the ActionEvent class instead
+of the Action class will be able to take advantage of what happens next...
+</p>
+
+<source><![CDATA[
+public class NewUser extends VelocityAction
+{
+    public void doAdd (PipelineData data, Context context) throws Exception
+    {
+        // put code here to add the user to the system
+        context.put ("username", username );
+        getRunData(data).setMessage("User Added!");
+    }
+
+    @TurbineActionEvent("save")
+    public void saveUser (PipelineData data, Context context) throws Exception
+    {
+        // put code here to save the modified user to persistent storage
+        getRunData(data).setMessage("User Saved!");
+    }
+
+    public void doPerform(PipelineData data, Context context) throws Exception
+    {
+        getRunData(data).setMessage("Button not found!");
+    }
+}
+]]></source>
+
+<p>
+Then, write your HTML tags specially like this:
+</p>
+
+<source><![CDATA[
+<input type="submit" name="eventSubmit_doAdd" value="Add User">
+<input type="submit" name="eventSubmit_save" value="Save User">
+]]></source>
+
+<p>
+When your Action is executed, an "event" is sent to it by attempting
+to execute a "doAdd()" method in your Action or a method annotated with the
+event name "save", respectively. The cool thing about this
+is that each of your "actions" that are performed within your Action class
+now are componentized into a single method that can be javadoc'ed individually.
+The annotation adds the possibility to name your events and methods any way you
+like.
+</p>
+
+<p>
+This new functionality does not mean that you should write all of your
+actions in one single class, what it means is that if you have a screen
+with many buttons on it that are very specific to that screen, it might
+be a good idea to place all those methods into a single class. This allows
+you to do it easily and also prevents you from having to do a "if then
+elseif" tree to figure out which button was clicked.
+</p>
+
+<p>
+For a catchall, the doPerform() method will be executed if no other
+method or button could be found.
+</p>
+
+<p>
+Because all keys processed by ParameterParser are subject to URL
+case folding, (in default mode lowercase), we have
+to do some work to format the string into a method name. For example, a
+button name eventSubmit_doDelete gets converted into eventsubmit_dodelete.
+Thus, we need to form some sort of naming convention so that dodelete can
+be turned into doDelete.
+</p>
+
+<p>
+Thus, the convention is this:
+<ul>
+    <li>The variable name MUST have the prefix "eventSubmit_".</li>
+    <li>The variable name after the prefix MUST begin with the letters "do".</li>
+    <li>The first letter after the "do" will be capitalized and the rest will be
+        lowercase</li>
+</ul>
+</p>
+
+<p>
+If you follow these conventions, then you should be ok with your method
+naming in your Action class. If you make use of the <code>@TurbineActionEvent</code>
+annotation, you can get rid of the latter two limitations and name your events
+methods as you like. Note that the event names are still subject to URL
+case folding, so that by default, <code>@TurbineActionEvent("save")</code>
+and <code>@TurbineActionEvent("Save")</code> are identical - unless you
+run the ParameterParser with URL case folding set to NONE.
+</p>
+
+<p>
+There is a property in the TurbineResources.properties file, called "action.eventsubmit.needsvalue".
+If you set this to "true", only the events that contain a non-empty, non-zero value will be
+executed. This is useful if you have a form with multiple, different events, that need to be executed
+and the form is submitted by client-side code, e.g. JavaScript.
+</p>
+<p>
+If you want to trigger an action event from an html link, versus a button, then just add a parameter with the name eventSubmit_doMyaction.
+The value can be anything as the name is all that is important.
+</p>
+</section>
+
+</body>
+</document>
diff --git a/src/site/xdoc/howto/annotations.xml b/src/site/xdoc/howto/annotations.xml
new file mode 100644
index 00000000..015212aa
--- /dev/null
+++ b/src/site/xdoc/howto/annotations.xml
@@ -0,0 +1,177 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<document>
+
+ <properties>
+  <title>Annotations Howto</title>
+ </properties>
+
+<body>
+
+<section name="Annotations">
+
+<p>
+Turbine provides a number of annotations to inject dependencies into your actions,
+screens and layouts. All <code>Assemblers</code> that is, all modules of type
+<code>Action</code>, <code>Screen</code>, <code>Layout</code>, <code>Page</code>,
+<code>Navigation</code> and <code>ScheduledJob</code> as well as all
+<code>Valves</code> in the pipeline support the injection of services,
+configurations and loaders. This relieves you from the burden of looking
+them up at runtime and thus simplifies and accelerates the code.
+</p>
+
+<subsection name="@TurbineService">
+The annotation can only be used with a field.
+A declared field in a class annotated with <code>@TurbineService</code>
+gets injected an instance of this service at the time the instance
+of the class is created. The field should have the type of the service
+interface like in the following two examples:
+<source><![CDATA[
+// Explicit service name
+@TurbineService( "RunDataService" )
+private RunDataService runDataService;
+
+// Implicit SERVICE_NAME or ROLE
+@TurbineService
+private FactoryService factory;
+]]></source>
+This is the equivalent of
+<source><![CDATA[
+runDataService = (RunDataService) TurbineServices
+    .getInstance().getService("RunDataService");
+
+factory = (FactoryService) TurbineServices
+    .getInstance().getService(FactoryService.ROLE);
+]]></source>
+As you an see, the annotation supports an optional parameter, the
+name of the service in the Turbine service repository. If this
+parameter is not present, the annotation processor will look
+for the field <code>SERVICE_NAME</code> and then <code>ROLE</code>
+in the type class of the field to retrieve the service name. If none
+of them can be found, the fully qualified class name of the
+service interface is used to look up the service.
+<br />
+If the service instance cannot be found, the annotation processor
+will throw an exception.
+</subsection>
+
+<subsection name="@TurbineConfiguration">
+The annotation can only be used with a field.
+If a declared field of the type <code>Configuration</code> is annotated
+with <code>@TurbineConfiguration</code>, Turbine will inject an instance
+of the Turbine configuration object at the time the instance of the class
+is created.
+<source><![CDATA[
+// Injected configuration instance
+@TurbineConfiguration
+private Configuration config;
+
+// Injected configuration subset instance
+@TurbineConfiguration( "action" )
+private Configuration actionConfig;
+]]></source>
+This is the equivalent of
+<source><![CDATA[
+config = Turbine.getConfiguration();
+
+actionConfig = Turbine.getConfiguration().subset("action");
+]]></source>
+The annotation supports an optional parameter, the
+prefix of the configuration subset to retrieve.
+<br />
+If other fields having simple types are annotated with
+<code>@TurbineConfiguration</code>, Turbine will inject the corresponding
+configuration value. In this case, the annotation parameter defines the
+configuration key and is required. Strings, Lists and most simple types
+are supported. The value will only be set if the key is found in the
+configuration, so that the field can be initialized with a default value.
+<source><![CDATA[
+// Injected configuration value
+@TurbineConfiguration( "module.cache" )
+private boolean moduleCache = true;
+
+@TurbineConfiguration( "template.homepage" )
+private String templateHomepage;
+]]></source>
+This is the equivalent of
+<source><![CDATA[
+moduleCache = Turbine.getConfiguration().getBoolean("module.cache", true);
+templateHomepage = Turbine.getConfiguration().getString("template.homepage");
+]]></source>
+</subsection>
+
+<subsection name="@TurbineLoader">
+The annotation can only be used with a field.
+A declared field in a class annotated with <code>@TurbineLoader</code>
+gets injected an instance of the specified <code>Loader</code> at
+the time the instance of the class is created. The field should have
+the type of the loader.
+<source><![CDATA[
+// Injected loader instance
+@TurbineLoader( Action.class )
+private ActionLoader actionLoader;
+]]></source>
+This is the equivalent of
+<source><![CDATA[
+actionLoader = TurbineAssemblerBroker.getLoader(Action.class);
+]]></source>
+The annotation parameter is required and defines the type of module
+that is to be loaded.
+</subsection>
+
+<subsection name="@TurbineActionEvent">
+The annotation can only be used with a method.
+A method in a class annotated with <code>@TurbineActionEvent</code>
+is associated to a named action event. The annotation parameter
+is required and defines the name of the event. See the
+<a href="action-event-howto.html">Action Events Howto</a>
+for usage and examples.
+</subsection>
+
+<subsection name="@TurbineTool">
+The annotation can only be used with a field.
+A declared field in a class annotated with <code>@TurbineTool</code>
+gets injected an instance of the specified <code>ApplicationTool</code> at
+the time the instance of the class is created. The field should have
+the type of the tool.
+<source><![CDATA[
+// Injected loader instance
+@TurbineTool( TemplateLink.class )
+private TemplateLink templateLink;
+]]></source>
+Normally a tool needs an context (request, global, user). You have to set the context by calling the 
+tool.init(Object object) method. E.g. in action methods you have access to request and session context objects.
+The annotation parameter is required and defines the type of the tool.
+</subsection>
+
+<subsection name="Performance Considerations">
+It is important to note that the processing of the annotations at
+the time the module class is instantiated takes some time. It is
+therefore strongly recommended to re-use the module instances in
+a production environment by setting the configuration parameter
+<code>module.cache</code> to <code>true</code> in
+<code>TurbineResources.properties</code>.
+</subsection>
+
+</section>
+
+</body>
+</document>
diff --git a/src/site/xdoc/howto/configuration-howto.xml b/src/site/xdoc/howto/configuration-howto.xml
new file mode 100644
index 00000000..c906498f
--- /dev/null
+++ b/src/site/xdoc/howto/configuration-howto.xml
@@ -0,0 +1,144 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<document>
+
+<properties>
+    <title>Configuration Howto</title>
+</properties>
+
+<body>
+
+<section name="Configurating Turbine">
+<p>
+With Turbine 2.3, there are now two different ways to configure Turbine.  The old
+classic way was to provide a TurbineResources.properties file in the standard
+properties format.  However, added to 2.3 is the ability to specify an XML based
+TurbineConfiguration.xml file that instructs Turbine how to load properties from
+multiple sources.
+</p>
+</section>
+
+<section name="Why do I want multiple sources of configuration?">
+<p>
+In the classic development environment, the developer has one environment, there is
+a QA environment, and then production.  While all of these environments strive to be
+as similar as possible, there are often difference between them.  For instance, in
+the development environment, you might want to not have Turbine cache templates, that
+way, as you change them, they are just reloaded.  But in test and production you might
+need them to be non reloading for performance.  There are many other situations like this.
+</p>
+<p>
+This leads to complex build scripts where you try and customize properties based on what
+environment you are performing a build for.  The more complex the build is, the less frequently
+the development team performs them, which goes against Agile development principles.  The
+ability of Turbine to merge multiple configuration properties together allows developers to
+easily customize Turbine without resorting to complex build scripts.  A simple war:webapp is
+all you need for any environment!  Replacing something like build:dev, build:test, and build:live.
+</p>
+</section>
+
+<section name="Classic Configuration Using Single Property File">
+<p>
+The classic way of performing configuration is to provide the properties file via your
+web.xml file:
+</p>
+
+<source test=""><![CDATA[
+    <servlet>
+        <servlet-name>fortius</servlet-name>
+        <servlet-class>org.apache.turbine.Turbine</servlet-class>
+        <init-param>
+            <param-name>properties</param-name>
+                    <param-value>
+                            /WEB-INF/conf/TurbineResources.properties
+            </param-value>
+        </init-param>
+
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+]]></source>
+
+<p>
+This works well, but if you want to customize the various settings that Turbine uses to
+control it's behavior, then you need to provide a TurbineConfiguration.xml file!
+Reading from /WEB-INF/conf/TurbineResources.properties is actually the default fall back - if no init parameter is provided.
+</p>
+</section>
+
+<section name="TurbineConfiguration.xml File for Multiple Sources">
+<p>
+The TurbineConfiguration.xml file doesn't contain any configuration data itself, instead
+it points at other files that may have configuration data.  Turbine leverages Commons-Configuration's
+<code>DefaultConfigurationBuilder</code> to access the data.  For more information, look at
+the <a href="http://commons.apache.org/proper/commons-configuration/">Configuration</a>
+homepage.
+</p>
+
+<p>
+To specify the location of your TurbineConfiguration.xml file, just change your servlet init
+parameters to this:
+</p>
+<source test=""><![CDATA[
+    <servlet>
+        <servlet-name>fortius</servlet-name>
+        <servlet-class>org.apache.turbine.Turbine</servlet-class>
+        <init-param>
+            <param-name>configuration</param-name>
+            <param-value>
+                    /WEB-INF/conf/TurbineConfiguration.xml
+            </param-value>
+        </init-param>
+
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+]]>
+</source>
+
+<p>
+This file will contain lines like this:
+</p>
+
+<source test=""><![CDATA[
+<configuration>
+  <jndi className="org.apache.commons.configuration.JNDIConfiguration" prefix="java:comp/env"/>
+  <!-- CHANGE! As fileName is converted to URL internally now and applicationpath is prefixed fileName has to be a relative path, cft. RFC2396.  -->
+  <dom4j className="org.apache.commons.configuration.DOM4JConfiguration" fileName="WEB-INF/conf/OtherProperties.xml"/>
+  <properties className="org.apache.commons.configuration.PropertiesConfiguration" fileName="WEB-INF/conf/TurbineResources.properties"/>
+</configuration>
+]]></source>
+
+<p>
+The configurations specified first override the values of configurations specified
+afterwards.  So, if the configuration value "mail.server" is specified as mymailserver.mycompany.com in
+your JNDI settings, and localhost in the TurbineResources.properties, then when you issue:
+</p>
+<source>
+	String mailServer = Turbine.getConfiguration().get("mail.server");
+</source>
+<p>
+Then the mailServer value returned will be "mymailserver.mycompany.com".  However, if you
+don't have a setting specified in your JNDI settings, then this would return "localhost".
+</p>
+
+</section>
+
+</body>
+</document>
diff --git a/src/site/xdoc/howto/context-howto.xml b/src/site/xdoc/howto/context-howto.xml
new file mode 100644
index 00000000..bd3ec58b
--- /dev/null
+++ b/src/site/xdoc/howto/context-howto.xml
@@ -0,0 +1,472 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<document>
+
+<properties>
+    <title>Context Howto</title>
+</properties>
+
+<body>
+
+<section name="Using the Turbine Context">
+<p>
+The Turbine Templating Services attach references to default Objects in the
+Turbine Context as part of their initialization. In the case of the
+TurbineVelocityService these references point to RunData, TemplateLink and
+TemplatePageAttributes. These three are put into the Context in the
+TurbineVelocityService class. The Context stores the Objects in a Hashtable
+with a key and the Object.
+</p>
+</section>
+
+<section name="Using the RunData Object">
+<p>
+The RunData Object is referenced by the "data" keyword, which when using this
+in the templating system is referenced by $data. As the Context contains a link
+to the RunData object all the public methods in the RunData Object are made
+available to the template. For example, typing $data.getMessage() will access
+the message String being stored in the RunData Object and print that as part
+of the templates output.
+</p>
+
+<p>
+RunData exposes an extremely rich series of methods and fields, for a full list
+of these methods refer to the Javadocs for RunData. Some of the useful methods
+exposed in RunData include;
+</p>
+
+<p>
+<ul>
+    addMessage(String msg) <br />
+    getMessage() <br />
+    getParameters() <br />
+    getServerName() <br />
+    getTitle() <br />
+    getUser() <br />
+    removeUserFromSession() <br />
+    setMessage(String message) <br />
+    setRedirectUri(String ruri) <br />
+    setTitle(String title) <br />
+    setLayoutTemplate(String title) <br />
+</ul>
+</p>
+
+<p>
+The RunData also allows for access to the TemplateInfo Object via
+getTemplateInfo() and several convenience methods. This allows for properties
+of the Templates to be modified for a Request when using templating systems like
+Velocity, WebMacro or Freemarker.
+</p>
+
+<p>
+As an example assume we want a printable page that contains only the Templating
+Screen and not all the navigational components. To achieve this we can strip
+out all the non screen templating components by describing a new Layout Template
+called PrintableLayout.vm in the templates/layouts directory. All the
+PrintableLayout needs contain is;
+</p>
+
+<source test=""><![CDATA[
+    $screen_placeholder
+]]></source>
+
+<p>
+Without the references to the $navigation.setTemplate() methods in the template
+no navigational screen will be called. In the Screen Template that wants to take
+advantage of the PrintableLayout Template add to the Template;
+</p>
+
+<source test=""><![CDATA[
+    $data.setLayoutTemplate("/PrintableLayout.vm")
+]]></source>
+
+<p>
+This will strip the Screen Template of its Navigational components. These
+convenience methods can also be used to expose and to set the Layout when the
+Template is processed. Through this a User can potentially choose how they would
+like their webpage to appear by choosing one of many differant Layouts or
+choices you, the webdesigner provide.
+</p>
+</section>
+
+<section name="Using the TemplateLink Object">
+<p>
+The TemplateLink is an extended version of DynamicURI customised to be used in
+the templates. The TemplateLink is referenced in the templates via $link and
+exposes convenience methods for building URI's on the fly. For example in a
+template to build the URI to another template, TemplateLink would be referenced
+via;
+</p>
+
+<source test=""><![CDATA[
+    $link.setPage("newpage.vm")
+]]></source>
+
+<p>
+which when added to a Velocity template would (depending on the servlet
+configuration) return;
+</p>
+
+<p>
+<blockquote>
+    http://127.0.0.1:8080/newapp/servlet/newapp/template/index.vm
+</blockquote>
+</p>
+
+<p>
+where "newapp" is the chosen webapp deployment name.
+</p>
+
+<p>
+This same mechanism can also be used to link to static html;
+</p>
+
+<source>
+    $link.setPage("/path/to/static.html")
+</source>
+
+<p>
+However the HTML page will load itself into a screen and not be embedded withint the Layouts and Navigations. If you still wish static content to be embedded within the specified layouts and navigations it is easier to add the static content as a velocity template and not take advantage of any of the dynamic content addition the Velocity Context allows.
+</p>
+
+
+<p>
+TemplateLink and DynamicURI again expose a rich set of methods and fields to
+the link reference, for a full list of fields and methods please refer to
+TemplateLink and DynamicURI in the javadocs. Some of the useful methods
+exposed are;
+</p>
+
+<p>
+<ul>
+    setPage(String templatename) <br />
+    addPathInfo(ParameterParser pp) <br />
+    addPathInfo(String name, String value) <br />
+    addQueryData(ParameterParser pp) <br />
+    addQueryData(String name, String value) <br />
+    getScriptName() <br />
+    getServerData() <br />
+    getServerPort() <br />
+    setAction(String action) <br />
+    setScreen(String screen) <br />
+    setSecure() <br />
+</ul>
+</p>
+</section>
+
+<section name="Using the TemplatePageAttributes Object">
+<p>
+The TemplatePageAttributes is accessed from within the context by the keyword
+"page" and provides methods to modify the various HTML attributes of the
+templating system. The Template context can be used to dictate the style of
+the HTML page in the navigation and layout templates as well as modify these
+attributes from within a screen.
+</p>
+
+<p>
+As an example in the default.vm the page can be set to a maroon background with;
+</p>
+
+<source test=""><![CDATA[
+    $page.setBgColor("#800000")
+]]></source>
+
+<p>
+the screen template may need to set a new title to the page being displayed in
+the browser, this can be done in the screen template via;
+</p>
+
+<source test=""><![CDATA[
+    $page.setTitle("New Title to Page")
+]]></source>
+
+<p>
+Non standard attributes can be added to the Body tag, for instance the
+leftmargin or topmargin attributes via;
+</p>
+
+<source test=""><![CDATA[
+    $page.addAttribute("topmargin", 0)
+]]></source>
+
+<p>
+Note though that the addAttribute method only adds attributes to the Body tag.
+For a full list of methods exposed to the page reference view the Javadocs for
+TemplatePageAttributes. Other methods exposed to the page reference are;
+</p>
+
+<p>
+<ul>
+    addAttribute(String name, String value) <br />
+    getTitle() <br />
+    setBackground(String url) <br />
+    setBgColor(String color) <br />
+    setDescription(String description) <br />
+    setKeywords(String description) <br />
+    setLinkColor(String color) <br />
+    setStyleSheet(String url) <br />
+    setTextColor(String color) <br />
+    setTitle(String title) <br />
+    setVLinkColor(String color) <br />
+</ul>
+</p>
+</section>
+
+<section name="Adding your own Objects to the Context">
+<p>
+As the Context is stored as a Hashtable any Object can be placed inside
+it and be accessed from a template. For instance, in a Velocity Screen
+in the doBuildTemplate() method, a String could be added to the Context.
+Please refer to the <a href="../getting-started.html">Getting
+Started</a> documentation for more examples of using the Velocity
+Context with screens and events.
+</p>
+
+<source test=""><![CDATA[
+    context.put("hello",new String("testing"));
+]]></source>
+
+<p>
+This can be referenced from within the template via;
+</p>
+
+<source test=""><![CDATA[
+    $hello the hello reference
+]]></source>
+
+<p>
+which would be output as;
+</p>
+
+<source test=""><![CDATA[
+    testing the hello reference
+]]></source>
+</section>
+
+<section name="Using an Image Object in the Context">
+<p>
+Creating an HTML link to an image from a template could be done by;
+</p>
+
+<source test=""><![CDATA[
+   $link.getServerScheme()
+   ://
+   $link.getServerName()
+   :
+   $link.getServerPort()
+   /context/imagename.jpg
+]]></source>
+
+<p>
+This has been split up into multiple lines for clarity. Doing this once is a
+pain, doing it twice stinks, if the screen requires several images .... and
+there are many screens .... it is a productivity killer. The Velocity Context
+can be used to store this information and expose it to all the Screens
+requiring it. To do this we can create an Image Object which extends the Turbine
+DynamicURI Object. The following class is Jakarta Tomcat specific;
+</p>
+
+
+<source test=""><![CDATA[
+//Turbine
+import org.apache.turbine.util.DynamicURI;
+import org.apache.turbine.util.RunData;
+
+
+public class Image extends DynamicURI
+{
+
+    /** The images directory */
+    public static final String DIR = "images";
+
+    /** tomcat specific - tomcat context */
+    private String contextpath;
+
+    /** Constructor */
+    public Image (RunData data)
+    {
+        super(data);
+
+        //the Tomcat context
+        contextpath = data.getRequest().getContextPath();
+    }
+
+    /** set the image and URI */
+    public String setImage(String imagename)
+    {
+        return (
+        getServerScheme() + //http
+        "://" +
+        getServerName()  + //www.foo.com
+        ":" +
+        getServerPort() + //port webserver running on
+
+        //the context for tomcat adds a / so no need to add another
+
+        contextpath  +  //the tomcat context
+        "/" +
+        Images.DIR +
+        "/" +
+        imagename);
+    }
+}
+]]></source>
+
+<p>
+This can be instantiated from within the doBuildTemplate method in a Velocity
+Screen and added to the context from there;
+</p>
+
+<source test=""><![CDATA[
+    public void doBuildTemplate(RunData data, Context context) throws Exception
+    {
+        Image image = new Image(data);
+        context.put("image",image);
+    }
+]]></source>
+
+<p>
+from this the Image Object is accessible from within the corresponding screen
+template and can be accessed by;
+</p>
+
+<source test=""><![CDATA[
+    $image.setImage("imagename.jpg");
+]]></source>
+
+<p>
+Which is much simpler than the original attempt at dynamically creating an image
+URL. To make this Image object accessible across all Screens, sublass the
+VelocityScreen Object with one that overrides the doBuildTemplate() method by
+adding the Image object to the Velocity Context. Then use this class as the
+parent class for the Screens that need access to the Image Object. For more
+detail on taking advantage and extending the VelocityScreen Object, please view
+the <a href="../getting-started.html">Getting Started</a> Document.
+</p>
+
+<p>
+The above Image Object can also be modified to include any static data required
+by the templates. For instance CSS files, JavaScript files etc. Instead of an
+Image Object, it can be rewritten as a StaticLink Object;
+</p>
+
+<source test=""><![CDATA[
+//Turbine
+import org.apache.turbine.util.DynamicURI;
+import org.apache.turbine.util.RunData;
+
+
+public class StaticLink extends DynamicURI
+{
+
+    /** the images directory */
+    public static final String IMAGES = "images";
+
+    /** the css directory */
+    public static final String CSS = "css";
+
+    // etc
+
+    /** tomcat specific - tomcat context */
+    private String contextpath;
+
+    /** Constructor */
+    public Image (RunData data)
+    {
+        super(data);
+
+        //the Tomcat context
+        contextpath = data.getRequest().getContextPath();
+    }
+
+    /** set the image and URI */
+    public String setImage(String imagename)
+    {
+        //URI Logic
+    }
+
+    /** set the CSS style and URI*/
+    public String setCss(String stylesheet)
+    {
+        //URI Logic
+    }
+
+    /** general set method, input as string
+     *  ie can be set as $staticlink.setStaticLink("images/imagename")
+     */
+    public String setStaticLink(String staticlink)
+    {
+        //URI Logic
+    }
+
+}
+
+]]></source>
+</section>
+
+<section name="Using the Context Object with the Base/Peer OM">
+<p>
+As a more complex example, assume we are building a book archive system,
+where users can search for books by author and title. If we search on author
+"Greg Egan" and title "Permutation City", we can query the database through the
+base\peer system and return a Book Object that contains the information on the
+book "Permutation City". The Book Object would be placed in the context via;
+</p>
+
+<source test=""><![CDATA[
+    Book book = new Book();
+
+    //add the data to the Book Object
+    //from the Base/Peer Objects for Book
+
+    context.put("book", book);
+
+]]></source>
+
+<p>
+and then accessed in the velocity template by;
+</p>
+
+<source test=""><![CDATA[
+    $book.getAuthor()
+    $book.getTitle()
+]]></source>
+
+<p>
+where the two methods are public methods in the Book Object, in this case built
+by the <a href="torque.html">Torque Tool</a>. These methods would return;
+</p>
+
+<source test=""><![CDATA[
+    Greg Egan
+    Permutation City
+]]></source>
+
+<p>
+It is important not to try and put Objects with value null into the Context.
+A NullPointerException will be returned. This above example is intended to get
+across how the Velocity Context can be used to store data from the Base/Peer
+system that can be accessed from the Templates.
+</p>
+</section>
+
+</body>
+</document>
diff --git a/src/site/xdoc/howto/extend-user-howto.xml b/src/site/xdoc/howto/extend-user-howto.xml
new file mode 100644
index 00000000..6a7fb00b
--- /dev/null
+++ b/src/site/xdoc/howto/extend-user-howto.xml
@@ -0,0 +1,702 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<document>
+
+  <properties>
+    <title>Extend User Howto</title>
+  </properties>
+
+  <body>
+
+    <section name="Important note">
+      <p>
+        The information in this HOWTO pertains to Turbine 2.2.  Please refer
+        to the <a href="../services/security-service.html">Torque
+        Security Service</a> page for information on extending TurbineUser
+        in Turbine 2.3 and beyond.
+      </p>
+    </section>
+    <section name="Introduction">
+      <p>
+        This is a HOWTO on extending the TurbineUser and its
+        functionality.  The motivating factors for extending TurbineUser
+        are:
+        <ol>
+          <li>
+            to be able to make use of TURBINE_USER.USER_ID as a foreign key in
+            application tables; and
+          </li>
+          <li>
+            to be able to represent additional user attributes by adding columns
+            to TURBINE_USER.
+          </li>
+        </ol>
+      </p>
+      <p>
+        The example herein uses a very simple object model with only one table.
+        This table would be defined in your project-schema.xml file.
+        To illustrate solutions to both of our motivators we will:
+        <ol>
+          <li>
+            Add a REVIEWED_BY_USER_ID column to the BOOK application table.  This will
+              also include a foreign key reference back to TURBINE_USER.
+          </li>
+          <li>
+            Add a TITLE column to TURBINE_USER.
+          </li>
+        </ol>
+      </p>
+      <p>
+        <b>Important Note:</b> This solution is functionally incomplete in that
+        it does not support the ability to use TurbineUser as a commit point for
+        a transaction.  See the very end of this document for further details.
+      </p>
+
+      <p>
+          It is also important to note that this HOWTO is intended for use with
+          the database implementation of the SecurityService.  I will not address
+          how to extend TurbineUser for use with any other implementation.
+      </p>
+    </section>
+
+    <section name="How does TurbineUser actually work?" >
+
+        <p>
+            The inplementation of TurbineUser and TurbineUserPeer is distributed
+            with Turbine in the <code>org.apache.turbine.om.security</code>
+            package.  It is _NOT_ generated by Torque at this time.  There are
+            no corresponding Base* classes nor a TurbineUserMapBuilder either.
+        </p>
+        <p>
+            TurbineUser implements the User interface (from the same package).
+            This interface is used by the Security Service and a few other
+            services as well.  This is the reason behind not generating TurbineUser
+            through Torque.  It would have no idea how to provide an implementation
+            of the User interface leaving that inplementaion to you.
+        </p>
+        <p>
+            The MapBuilder for TurbineUser is
+            <code>org.apache.turbine.util.db.map.TurbineMapBuilder</code>.  This
+            MapBuilder is also used by Turbine for the other Turbine* classes
+            that are defined in the turbine-schema.xml file distributed with Turbine.
+        </p>
+        <p>
+            The turbine-schema.xml file is the source of a small problem.  The ant task
+            used to generate your OM layer will generate OM objects for all of the tables
+            defined in this file along with the MapBuilders.  These classes do not really
+            hurt anything but they can be a source of confusion.  There are not used
+            by Turbine for anything!
+        </p>
+        <p>
+            One valid reason for leaving this file in place is for the ant task that will
+            create your database schema for you.  Since the task will not modify the schema
+            for you after it is created (to add/remove columns, indexes, etc), it is of
+            little use after the database is created other than to serve as a reference.
+        </p>
+        <p>
+            Later in this discussion, you will be given instruction to rename this file to
+            prevent it from being used by the ant tasks as well as removing any objects
+            generated as a result.
+        </p>
+        <p>
+            Another interesting fact about TurbineUser is the way in which data stored in
+            the database is accessed.  Instead of using using private attributes for storage
+            within the object, all attibutes are stored in a hashtable (known herein as the
+            perm hashtable).  Access to the perm hashtable is controlled through the
+            getPerm/setPerm methods.
+        </p>
+        <p>
+            When the object is returned from the database, data from the columns are
+            added to the perm hashtable for you.  When you save the object, the data
+            is removed from the perm hashtable and written to the appropriate database
+            columns.
+        </p>
+        <p>
+            As you will read later, any data left in the perm hashtable that does
+            not have a mapped database column (more on this later)
+            during the save operation will be serialized and written to the
+            TURBINE_USER.OBJECTDATA column.
+        </p>
+        <p>
+            Another very nice feature of TurbineUser is the getTemp/setTemp
+            methods.  This allows you to store data in TurbineUser for the duration
+            of the session.  It will not be written to your persistent storage.
+            It is ONLY for the session.  Keep in mind that the login action will
+            replace the user object in the session with a user object from your
+            persistent storage thus removing any data you might have stored in the
+            user.
+        </p>
+
+    </section>
+
+    <section name="Modifications to project-schema.xml">
+      <p>
+        Here is the sample project-schema.xml file before making modifications
+        to reference TURBINE_USER.
+      </p>
+      <source>
+<![CDATA[
+<database defaultIdMethod="native" defaultJavaType="object">
+    <table name="BOOK">
+        <column name="BOOK_ID" required="true" primaryKey="true" type="INTEGER"/>
+        <column name="TITLE" required="true" type="VARCHAR"/>
+        <column name="AUTHOR" required="true" type="VARCHAR"/>
+    </table>
+</database>
+]]>
+      </source>
+      <p>
+        First we update the schema to include an alias definition of TurbineUser
+        as well as the desired foreign key
+        references.  Note how the TurbineUser definition refers to a pair of
+        adapter classes (we will create these shortly) and how it is only
+        necessary to define the columns we are referring to as foreign keys
+        elsewhere in the application database.  Note also the addition of
+        REVIEWED_BY_USER_ID as a foreign key in the BOOK table.
+      </p>
+      <source>
+<![CDATA[
+<database defaultIdMethod="native" defaultJavaType="object">
+    <table name="EXTENDED_USER" alias="TurbineUser"
+            baseClass="org.mycompany.sampleapp.om.TurbineUserAdapter"
+            basePeer="org.mycompany.sampleapp.om.TurbineUserPeerAdapter">
+        <column name="USER_ID" required="true" primaryKey="true" type="INTEGER"/>
+    </table>
+    <table name="BOOK">
+        <column name="BOOK_ID" required="true" primaryKey="true" type="INTEGER"/>
+        <column name="TITLE" required="true" type="VARCHAR"/>
+        <column name="AUTHOR" required="true" type="VARCHAR"/>
+        <column name="REVIEWED_BY_USER_ID" type="INTEGER"/>
+        <foreign-key foreignTable="EXTENDED_USER">
+            <reference local="REVIEWED_BY_USER_ID" foreign="USER_ID"/>
+        </foreign-key>
+    </table>
+</database>
+]]>
+      </source>
+        <p>
+            Notice the attribute on the database tag for defaultJavaType.  I used
+            "object" as the value.  The default is "primitive".  You do not have to
+            use "object"!!!
+        </p>
+        <p>
+            Turbine Version 2.1 only: In this version of Turbine, the only option was to use the
+            primitive types.  However, this posed a small problem.  It was not
+            possible to have number or boolean types that contained null values.
+            If a null value was found in the database for columns of these types,
+            the value returned from the OM object was 0 or false, respectively.
+            This also implies that you can not have non-required foreign key
+            references back to TURBINE_USER.  The primary key of TURBINE_USER
+            is a number.
+        </p>
+    </section>
+
+    <section name="Deciding how additional data in Turbine User will be stored">
+      <p>
+          There are two ways in which additional data in your extended TurbineUser
+          object can be stored.  The first, and simplest method, is to store it in
+          the perm hashtable.  As described earlier, any data in the perm hashtable
+          not mapped to a database column will get serialized into the
+          TURBINE_USER.OBJECTDATA column.  The second, and perferred method, is to
+          use additional database column(s) for storage.
+      </p>
+      <p>
+          Although storing the additional data in the TURBINE_USER.OBJECTDATA
+          column is the simplest method, it has a few drawbacks.
+          <ol>
+              <li>
+                  You will not have easy access to the data through SQL.
+              </li>
+              <li>
+                  You will not be able to specify criteria to select TurbineUser
+                  objects from the database by filtering on data stored in
+                  TURBINE_USER.OBJECTDATA.
+              </li>
+              <li>
+                  There is an upper limit to the amount of data that can be stored
+                  in the TURBINE_USER.OBJECTDATA column.  A few users have reported
+                  on the mailing list that they ran into this problem.  The limit
+                  will vary from one database to another.  This limit is reduced
+                  by persistent pull tools (see the docs on the PullService for
+                  details), if you have any in your project,
+                  as they are stored using this method by the PullService.
+              </li>
+          </ol>
+      </p>
+      <p>
+          If you do decide to store some of your additional attributes
+          in the TURBINE_USER.OBJECTDATA column, you need to be careful
+          of possible conflicts with the keys used in the perm hashtable by
+          TurbineUser.  When
+          the object is saved to the database, this data is removed from the
+          perm hashtable and written to the correct columns.  The keys used in the
+          perm hashtable are the uppercase names of the columns.  The column names
+          are not fully qualified with the names of the table like
+          <code>TURBINE_USER.LAST_NAME</code>.  Instead the key used is
+          <code>LAST_NAME</code>.  See
+          <code>org.apache.turbine.util.db.map.TurbineMapBuilder</code> for a
+          complete list of the keys used for the default columns.
+      </p>
+      <p>
+          If you choose to use additional database columns, you will not have
+          any of the drawbacks mentioned above.  Using the additional columns
+          is the approach that should be taken unless you have a
+          <strong>VERY</strong> good reason not to do so.
+      </p>
+    </section>
+
+    <section name="Implementing adapter and map builder classes">
+        <p>
+            First, we will extend the map builder used by Turbine for the Turbine*
+            classes to add the additional column(s) that we will be using in
+            TURBINE_USER.
+        </p>
+        <source>
+<![CDATA[
+package org.mycompany.sampleapp.util.db.map;
+
+import org.apache.torque.Torque;
+import org.apache.torque.map.TableMap;
+import org.apache.turbine.util.db.map.TurbineMapBuilder;
+
+/**
+ * Used to add the mapping of additional columns into any of the
+ * TURBINE_* tables.  This can be implemented as an empty class
+ * if you are not adding any additional database columns.
+ */
+public class TurbineMapBuilderAdapter extends TurbineMapBuilder
+{
+    /*
+    * Note: The getUser_*() methods in this class should be static, but
+    * getTableUser() and the initial field level methods are incorrectly
+    * declared in TurbineMapBuilder and hence we must use non-static methods
+    * here.
+    */
+
+    /**
+     * Gets the name of the database column that we are adding to
+     * TURBINE_USER.
+     * @return The name of the database column.
+     */
+    public static String getTitle()
+    {
+        return "TITLE";
+    }
+
+    /**
+     * Gets the fully qualified column name (TABLE.COLUMN) that will be
+     * used to store the Title attribute in the extended TurbineUser object.
+     * @return The fully qualified database column name.
+     */
+    public String getUser_Title()
+    {
+        return getTableUser() + '.' + getTitle();
+    }
+
+    /**
+     * Creates the map used by Torque to persist the Turbine* objects
+     * to the TURBINE_* tables.
+     * @throws Exception generic error
+     */
+    public void doBuild() throws Exception
+    {
+        // the superclass version of the MapBuilder must be called to create
+        // the mappings for the default columns.
+        super.doBuild();
+
+        // When you add a column to the database map, the map must know
+        // what type of data will be stored in the column.  For that
+        // purpose, we will create a few dummy objects to serve as
+        // data type indicators.  Not all of them are used in our example.
+        Integer dummyInteger = new Integer(0);
+        Date dummyDate = new Date();
+        String dummyString = new String();
+
+        // Add extra column.
+        TableMap tMap = Torque.getDatabaseMap().getTable(getTableUser());
+        tMap.addColumn(getTitle(),dummyInteger);
+    }
+}
+]]>
+      </source>
+      <p>
+          Now we will implement the pair of adapters we referred to in our
+          schema.  First we implement TurbineUserAdapter to provide access
+          to the primary key as well any additional attibutes we are adding.
+      </p>
+      <source>
+<![CDATA[
+package org.mycompany.sampleapp.om;
+
+import org.apache.turbine.om.security.TurbineUser;
+import org.apache.torque.om.NumberKey;
+import org.apache.turbine.util.ObjectUtils;
+
+/**
+ * This class extends TurbineUser for the purpose of adding get/set methods
+ * for accessing additional attributes.
+ */
+public class TurbineUserAdapter extends TurbineUser
+{
+    /** Used as the key in the perm hashtable.  */
+    public static final String TITLE = "TITLE";
+
+    /**
+     * Gets the userId of the user.  This is also the primary key
+     * of the TURBINE_USER table.  The return type of Integer is
+     * valid only if the javaType for the ExtendedUser table
+     * is "object".  If it is "primative", the return type
+     * should be changed to int.
+     * @return the user id
+     */
+    public Integer getUserId()
+    {
+        return new Integer(((NumberKey)getPrimaryKey()).intValue());
+    }
+
+    /**
+     * Sets the title of the user.
+     * @param title the user's title
+     */
+    public void setTitle(String title)
+    {
+        setPerm(TITLE, title);
+    }
+
+    /**
+     * Gets the user's title
+     * @return the user's title
+     */
+    public String getTitle()
+    {
+        String tmp = null;
+        try
+        {
+            tmp = (String) getPerm(TITLE);
+            if ( tmp.length() == 0 )
+            tmp = null;
+        }
+        catch (Exception e)
+        {
+        }
+        return tmp;
+    }
+}
+]]>
+      </source>
+      <p>
+          Note: This class uses the setPerm and getPerm methods to
+          access the data even though we are going to use the TURBINE_USER.TITLE
+          column for storage.  As mentioned earlier, the data is removed from the
+          hashtable when the object is saved to the database and written to the
+          correct database column.  Likewise, the when the object is retrieving
+          data from the database, the data from the TURBINE_USER.TITLE column is
+          added to the perm hashtable with the TITLE key.
+      </p>
+      <p>
+          Next comes TurbineUserPeerAdapter to which we add details of the new
+          database columns.
+      </p>
+      <source>
+<![CDATA[
+package org.mycompany.newapp.om;
+
+import org.mycompany.sampleapp.util.db.map.TurbineMapBuilderAdapter;
+import org.apache.torque.om.ObjectKey;
+import org.apache.torque.util.Criteria;
+import org.apache.turbine.om.security.peer.TurbineUserPeer;
+
+/**
+ * This class extends TurbineUserPeer for the purpose of mapping additional
+ * database columns.  You can implement this as an empty class if you are not
+ * using any additional database columns.
+ */
+public class TurbineUserPeerAdapter extends TurbineUserPeer
+{
+    /** the default database name for this class */
+    public static final String DATABASE_NAME = "default";
+
+    /** Used to build the map for the extended Turbine User */
+    private static final TurbineMapBuilderAdapter mapBuilder =
+        (TurbineMapBuilderAdapter)getMapBuilder("org.mycompany.sampleapp.util.db.map.TurbineMapBuilderAdapter");
+
+    /** The fully qualified name of the database table */
+    public static final String TITLE = mapBuilder.getUser_Title();
+
+    /**
+     * Builds a criteria object to select by a primary key value.  Of course,
+     * it could also be used for an update or delete.
+     * @param pk Primary key to select/update/delete
+     * @return A Criteria object built to select by primary key
+     */
+    public static Criteria buildCriteria(ObjectKey pk)
+    {
+        Criteria crit = new Criteria();
+        crit.add(TurbineUserPeer.USER_ID, pk.getValue());
+
+        return crit;
+    }
+}]]>
+      </source>
+    </section>
+
+    <section name="Generating the OM layer">
+        <p>
+            Before generating the OM layer, see if you have a turbine-schema.xml
+            file in your WEB-INF/conf directory.  If you do, rename this file to
+            turbine-schema.xml.nogenerate.  Also, the only Turbine* classes that
+            you should have in your om package are the two adapters that you
+            created earlier.  Any other Turbine* or BaseTurbine* class in your om
+            package should be removed.  You should also remove any om.map.Turbine*
+            classes that might have been generated.
+        </p>
+        <p>
+
+            <b>Warning:  Do not run the init ant task after doing this.</b>
+            That task will drop and recreate your database.  Without the
+            turbine-schema.xml file present, the TURBINE_* tables will not
+            be recreated!
+        </p>
+        <p>
+            These classes were generated from the turbine-schema.xml file.  The
+            project-om ant task will process
+            any file in your WEB-INF/conf directory ending in <code>-schema.xml</code>
+            and generate the appropriate classes from that definition.  Renaming the
+            turbine-schema.xml file stops these extra classes from being generated.
+        </p>
+        <p>
+            Next, you will need to manually create any additional database columns
+            that you will be using in TURBINE_USER.  Make sure that the name of the
+            columns match what you speificied in TurbineUserPeerAdapter.
+        </p>
+        <p>
+            We can now use project-om ant task to generate our OM layer using
+            the adapter classes we defined above.
+        </p>
+        <p>
+            With any luck everything will compile okay and we are only a small step
+            away from being able to use the new OM layer.
+        </p>
+    </section>
+
+    <section name="Modifications to TurbineResources.properties">
+        <p>
+            The last step is to tell Turbine about the new classes we are using for
+            Users and MapBuilder.  To do this we need to update the following
+            entries in TurbineResources.properties:
+        </p>
+      <source>
+<![CDATA[
+database.maps.builder=org.mycompany.sampleapp.util.db.map.TurbineMapBuilderAdapter
+services.SecurityService.user.class=org.mycompany.sampleapp.om.ExtendedUser
+services.SecurityService.userPeer.class=org.mycompany.sampleapp.om.ExtendedUserPeer
+]]>
+      </source>
+        <p>
+            That is basically it.  We can now modify our application to utilise the
+            new columns via the methods defined in the OM objects we have modified.
+            Note that in order to access the new methods in ExtendedUser we need to cast
+            from TurbineUser thus:
+        </p>
+      <source>
+<![CDATA[
+ExtendedUser user = (ExtendedUser) data.getUser();
+]]>
+      </source>
+        <p>
+            Enjoy.
+        </p>
+    </section>
+
+    <section name="Additional Information">
+        <p>
+            For those of you that are attempting to extend TurbineUser to make use of
+            TURBINE_USER.USER_ID as a foreign key in your application tables here is
+            one small problem.
+        </p>
+        <p>
+            Torque generates some pretty useful code that enables you to add related
+            objects to a common parent object and then save them all to the database
+            in one transaction.  You can do something like this:
+        </p>
+        <source>
+<![CDATA[
+OrderDetail od1 = new OrderDetail(500, "item1");
+OrderDetail od2 = new OrderDetail(100, "item2");
+Order o = new Order(clientId);
+o.addOrderDetail(od1);
+o.addOrderDetail(od2);
+o.save();
+]]>
+        </source>
+        <p>
+            This is very helpful - you don't need to worry about the ids that connect
+            the child rows to the parent rows and you don't need to worry about the
+            transaction necessary to insert these into the database as one atomic
+            operation.  It also provides:
+        </p>
+        <source>
+<![CDATA[
+o.save(dbConn);
+]]>
+        </source>
+            <p>
+                which can be used when you have other data you want to commit in a
+                transaction you are managing yourself.
+            </p>
+            <p>
+                Now here is the problem.  After extending TurbineUser in the manner
+                described above, the methods are generated to add records related the
+                extended user class, but the data itself is ignored when
+                ExtendedUser.save() is invoked.  Here is an example:
+            </p>
+        <source>
+<![CDATA[
+Book book = new Book();
+data.getParameters().setProperties(book);
+ExtendedUser user = (ExtendedUser) data.getUser();
+user.addBook(book);
+user.save(); // !!!! book is not saved !!!!
+]]>
+        </source>
+            <p>
+                Of course replacing the last two lines with:
+            </p>
+        <source>
+<![CDATA[
+book.setReviewedByUserId(user.getUserId());
+book.save();
+]]>
+        </source>
+            <p>
+                will in fact save the Book, this is beside the point - the other method
+                addBook() shouldn't exist if it doesn't work and this is a trivial example.
+            </p>
+            <p>
+                In addition to this, there is no equivalent save(dbConn) method provided
+                to allow this update to be combined with others within a single database
+                transaction.
+            </p>
+            <p>
+                There are a few solutions to this problem.  One would be to fix the torque
+                template responsible for generating the code.  Another would be to implement
+                the methods yourself.  Before exploring either of these options, you need to
+                ask yourself if this problem will even affect you.  If not, don't worry about
+                it.
+            </p>
+            <p>
+                Implementing the methods yourself might be the simpliest route for someone
+                new to Turbine and Torque.  This simply involves overriding the addBook()
+                method in the example above with the two lines shown previously.  Of course,
+                You would have to do this for each and every one that Torque generates
+                for you.
+            </p>
+            <p>
+                The same idea applies to the save(dbConn) method.  Simply override that method
+                in your ExtendedTurbineUser class (or whatever you called your class) to perform
+                the operation correctly.  You can get sample code from one of the other classes
+                that Torque generated for you.
+            </p>
+            <p>
+                If you want Torque to generate to code for you, you will have to modify the
+                Object.vm template that Torque uses.
+            </p>
+            <p>
+                The other solution involves altering a torque template so that the code that
+                generates the aspects of the save() method that handle related tables is
+                allowed to execute for the TurbineUserAlias class.  You need to apply the
+                following patch (most likely to the version of Object.vm copied to the
+                WEB-INF/build/bin/torque/templates/om directory for your application):
+            </p>
+        <source>
+<![CDATA[
+Index: jakarta-turbine-2/conf/torque/templates/om/Object.vm
+===================================================================
+RCS file: /home/cvspublic/jakarta-turbine-2/conf/torque/templates/om/Object.vm,v
+
+retrieving revision 1.3
+diff -u -r1.3 Object.vm
+--- jakarta-turbine-2/conf/torque/templates/om/Object.vm        24 Oct 2001 18:1
+2:21 -0000      1.3
++++ jakarta-turbine-2/conf/torque/templates/om/Object.vm        16 Jan 2002 14:0
+0:43 -0000
+@@ -787,7 +787,7 @@
+#end     ## ends the if(addGetByNameMethod)
+
+
+-#if (!$table.isAlias() && $addSaveMethod)
++#if ((!$table.isAlias() || $table.Alias == "TurbineUser") && $addSaveMethod)
+/**
+* Stores the object in the database.  If the object is new,
+* it inserts it; otherwise an update is performed.
+@@ -880,6 +880,9 @@
+{
+alreadyInSave = true;
+#end
++    #if ($table.isAlias() && $table.Alias == "TurbineUser")
++        super.save();
++    #else
+if (isModified())
+{
+if (isNew())
+@@ -892,6 +895,7 @@
+${table.JavaName}Peer.doUpdate(($table.JavaName)this, dbCon);
+}
+}
++    #end
+
+#if ($complexObjectModel)
+#foreach ($fk in $table.Referrers)
+]]>
+        </source>
+            <p>
+                You will need to manually remove the line wrapping from the above
+                patch.  This patch is only included here to give you an idea of what
+                would need to be changed in Torque.  The patch can not be applied
+                to the current version of Torque simply because it is so outdated.
+            </p>
+            <p>
+                Notice how although you can go <code>user.save(dbCon);</code> the
+                TurbineUser record will not be part of the transaction.
+            </p>
+            <p>
+                I would suggest that you override the methods that do not
+                get generated correctly in your ExtendedTurbineUser class.  Do so ONLY
+                if this problem will affect you.
+            </p>
+            <p>
+                The real solution to this problem is in modifing Turbine in such a way to
+                allow Torque to generate the TurbineUser object.  This would eliminate the
+                need to extend TurbineUser altogether.  There would still be the need to add
+                additional columns and/or create FK references to the TURBINE_USER table.  It
+                would would only involve modifing the schema files and letting Torque do
+                all of the work instead of creating the adapter classes and modifing the
+                map builder.
+            </p>
+            <p>
+                Note:  The last solution mentioned should be ready for Turbine 2.3.  This
+                should make life easier for everyone!!!
+            </p>
+
+    </section>
+
+  </body>
+</document>
diff --git a/src/site/xdoc/howto/hibernate-howto.xml b/src/site/xdoc/howto/hibernate-howto.xml
new file mode 100644
index 00000000..e3455235
--- /dev/null
+++ b/src/site/xdoc/howto/hibernate-howto.xml
@@ -0,0 +1,572 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<document>
+
+  <properties>
+    <title>Hibernate Howto</title>
+  </properties>
+
+  <body>
+
+    <section name="Introduction">
+      <p>
+        This is a HOWTO on implementing Hibernate as the database OM layer.  The motivating factors for using Hibernate
+        are:
+        <ol>
+          <li>
+      You just use POJO (Plain Old Java Objects) versus generated objects.
+          </li>
+          <li>
+      You can either start with Java objects and create your database schema from there, or
+      start with a database schema, and map the Java objects to the schema.
+          </li>
+          <li>
+      Extensive performance optimizations built into the Hibernate engine.
+          </li>
+          <li>
+      Leverage Avalon component use in Turbine 2.3!
+          </li>
+        </ol>
+      </p>
+      <p>
+        Please review the content available from the Hibernate homepage.  This howto assumes
+        you already are confortable with the various Hibernate concepts.
+      </p>
+      <p>
+    In this example, we will take a simple schema with a single table and integrate Hibernate into
+    a Turbine action.  We will talk about best practices for Hibernate and Turbine.
+        <ol>
+          <li>
+        Configure project dependencies.
+          </li>
+          <li>
+        Directory Structures
+          </li>
+
+          <li>
+        Setup Avalon component configuration.
+          </li>
+
+          <li>
+          Setup Hibernate mapping files.
+          </li>
+          <li>
+          Create static ServiceLocator class.
+          </li>
+          <li>
+            Create filter that manages the Hibernate Session.
+          </li>
+          <li>
+            Setup PersitenceException handling
+          </li>
+        </ol>
+      </p>
+
+    </section>
+
+    <section name="Directory Structures">
+      <p>
+      While you can organize your directory structure however you like, I tend to have structure like:
+      </p>
+      <source>
+      /src/java/com/my/project/bizobj business objects reside
+      /src/java/com/my/project/om POJO objects mapped to database reside
+      /src/java/com/my/project/om/persist manager objects that faciliate retrieve POJO objects
+      /src/java/com/my/project/om/filter Servlet Filter lives that maintains the Hibernate Session
+      /src/java/ where hibernate.hbm.xml and hibernate.cfg.xml files live
+
+    </source>
+
+    </section>
+
+    <section name="Configure project dependencies" >
+      <p>
+        The easiest way to maintain a project is to use Maven.  Here are the sample
+        dependencies for your project.xml.
+      </p>
+      <source>
+<![CDATA[
+    <dependency>
+      <id>hibernate</id>
+      <version>2.0-beta6</version>
+      <properties>
+      <war.bundle.jar>true</war.bundle.jar>
+      </properties>
+    </dependency>
+    <dependency>
+      <id>hibernate:hibernate-avalon</id>
+      <version>0.1</version>
+      <properties>
+      <war.bundle.jar>true</war.bundle.jar>
+      </properties>
+    </dependency>
+    <dependency>
+      <id>dom4j</id>
+      <version>1.4</version>
+      <properties>
+      <war.bundle.jar>true</war.bundle.jar>
+      </properties>
+    </dependency>
+    <dependency>
+      <id>cglib</id>
+      <version>rc2-1.0</version>
+      <properties>
+      <war.bundle.jar>true</war.bundle.jar>
+      </properties>
+    </dependency>
+    <dependency>
+      <id>jcs</id>
+      <version>1.0-dev</version>
+      <properties>
+      <war.bundle.jar>true</war.bundle.jar>
+      </properties>
+    </dependency>
+]]>
+      </source>
+      <p>
+        The key jar file is the hibernate-avalon.jar file, it contains the Avalon wrapper
+        for Hibernate, and can be used with any Avalon container.
+      </p>
+
+    </section>
+
+    <section name="Setting up Avalon Configuration" >
+
+        <p>
+      We leverage the Avalon based HibernateService that is hosted as part of the
+      HibernateExt project.  You must specify the name of the service, as well as the implementing
+      service in your componentConfiguration.xml file.  Other configuration parameters can be passed
+      in as well.
+        </p>
+      <source>
+<![CDATA[
+
+<my-system>
+  <component
+    role="net.sf.hibernate.avalon.HibernateService"
+    class="net.sf.hibernate.avalon.HibernateServiceImpl">
+  </component>
+</my-system>
+
+]]>
+      </source>
+
+        <p>
+      The componentRoles file also defines how to access the component.  Here is a
+      very simple componentRoles.xml file:
+        </p>
+      <source>
+<![CDATA[
+
+<role-list>
+ <role
+    name="net.sf.hibernate.avalon.HibernateService"
+    shorthand="hibernate"
+    default-class="net.sf.hibernate.avalon.HibernateServiceImpl"/>
+</role-list>
+
+]]>
+      </source>
+    </section>
+
+
+
+    <section name="Setup Hibernate mapping files">
+      <p>
+    This section will not go into depth on how to configure the hibernate.cfg.xml and
+    hibernate.hbm.xml files.  However, if you don't specify in the componentConfiguration.xml
+    file where they are located, then they should be placed in your src/java/ directory.
+      </p>
+      <p>
+        The exact configuration is dependent on the environment Turbine is running in, however
+        I highly recommend that you use the JNDI look up of the datasource, and use DBCP for your
+        connection pooling.  I have found that when using Hibernate in cactus tests, you may need to
+        increase the pool size required in order to not run out of connections, however this doesn't
+        seem to apply to running as a web application.
+      </p>
+    </section>
+
+
+
+    <section name="Create static ServiceLocator class.">
+      <p>
+    Currently this class is not integrated into Turbine, so you will need to provide an implemation yourself.
+    This provides a static method of retrieving your Hibernate Session.
+      </p>
+
+        <source>
+<![CDATA[
+package com.upstate.cellculture.om.persist;
+
+import net.sf.hibernate.HibernateException;
+import net.sf.hibernate.JDBCException;
+import net.sf.hibernate.Session;
+import net.sf.hibernate.SessionFactory;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * This class is used to get Hibernate Sessions and may
+ * also contain methods (in the future) to get DBConnections
+ * or Transactions from JNDI.
+ */
+public class ServiceLocator
+{
+    //~ Static fields/initializers =============================================
+    public final static String SESSION_FACTORY = "hibernate/sessionFactory";
+    public static final ThreadLocal session = new ThreadLocal();
+    private static SessionFactory sf = null;
+    private static ServiceLocator me;
+    private static Log log = LogFactory.getLog(ServiceLocator.class);
+
+    static {
+        try
+        {
+            me = new ServiceLocator();
+        }
+        catch (Exception e)
+        {
+            log.fatal("Error occurred initializing ServiceLocator");
+            e.printStackTrace();
+        }
+    }
+
+    //~ Constructors ===========================================================
+
+    private ServiceLocator() throws HibernateException, JDBCException
+    {}
+
+    //~ Methods ================================================================
+
+    public static Session currentSession() throws PersistenceException
+    {
+        Session s = (Session) session.get();
+
+        if (s == null)
+        {
+            s = PersistenceManager.openSession();
+            if (log.isDebugEnabled())
+            {
+                log.debug("Opened hibernate session.");
+            }
+
+            session.set(s);
+        }
+
+        return s;
+    }
+
+    public static void closeSession() throws HibernateException, JDBCException
+    {
+        Session s = (Session) session.get();
+        session.set(null);
+
+        if (s != null)
+        {
+            if (s.isOpen())
+            {
+                s.flush();
+                s.close();
+
+                if (log.isDebugEnabled())
+                {
+                    log.debug("Closed hibernate session.");
+                }
+            }
+        }
+        else
+        {
+            log.warn("Hibernate session was inadvertently already closed.");
+
+        }
+    }
+}
+]]>
+      </source>
+    </section>
+
+    <section name="Create Servlet Filter.">
+      <p>
+        The servlet Filter is required if you use lazy loading of objects because you need to open a Hibernate sesion, and keeps it open through the view layer.
+        This ensures that each user get's their own Hibernate Session.  ?? Should this be done
+        through some sort of SessionValidator?
+
+      </p>
+
+        <source>
+<![CDATA[
+package com.upstate.cellculture.filter;
+
+import java.io.IOException;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import net.sf.hibernate.Session;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import com.upstate.cellculture.om.persist.PersistenceException;
+import com.upstate.cellculture.om.persist.ServiceLocator;
+
+public class ActionFilter implements Filter
+{
+    //~ Static fields/initializers =============================================
+
+    //~ Instance fields ========================================================
+
+    /**
+     * The <code>Log</code> instance for this class
+     */
+    private Log log = LogFactory.getLog(ActionFilter.class);
+    private FilterConfig filterConfig = null;
+
+    //~ Methods ================================================================
+
+    public void init(FilterConfig filterConfig) throws ServletException
+    {
+        this.filterConfig = filterConfig;
+
+    }
+
+    /**
+     * Destroys the filter.
+     */
+    public void destroy()
+    {
+        filterConfig = null;
+    }
+
+    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException
+    {
+        // cast to the types I want to use
+        HttpServletRequest request = (HttpServletRequest) req;
+        HttpServletResponse response = (HttpServletResponse) resp;
+        HttpSession session = request.getSession(true);
+
+        Session ses = null;
+        boolean sessionCreated = false;
+
+        try
+        {
+            chain.doFilter(request, response);
+        }
+        finally
+        {
+            try
+            {
+                ServiceLocator.closeSession();
+            }
+            catch (Exception exc)
+            {
+                log.error("Error closing hibernate session.", exc);
+                exc.printStackTrace();
+            }
+        }
+    }
+
+    public static Session getSession() throws PersistenceException
+    {
+        try
+        {
+
+            return ServiceLocator.currentSession();
+        }
+        catch (Exception e)
+        {
+            throw new PersistenceException("Could not find current Hibernate session.", e);
+        }
+
+    }
+}
+
+]]>
+      </source>
+    </section>
+
+
+
+
+
+
+    <section name="Implementing Manager classes">
+        <p>
+      To centralize access to the database, we create Manager classes.  Often Manager
+      classes are called DAO (Data Access Classes).  Here is an example:
+        </p>
+        <source>
+<![CDATA[
+/*
+ * Created on Apr 28, 2003
+ *
+ */
+package com.upstate.cellculture.om.persist;
+import java.util.List;
+
+import net.sf.hibernate.Query;
+import net.sf.hibernate.Session;
+
+import com.upstate.cellculture.om.Technician;
+/**
+ * @author tmckinney
+ *
+ * Centralizes all access to the Technicians table
+ */
+public class TechnicianManager
+{
+    private static List allTechnicians;
+    public static void save(Technician technician) throws PersistenceException
+    {
+        try
+        {
+
+            ServiceLocator.currentSession().save(technician);
+
+        }
+        catch (Exception e)
+        {
+            throw new PersistenceException("Could not save.", e);
+        }
+    }
+
+    public static Technician retrieveByPK(long technicianId) throws PersistenceException
+       {
+           try
+             {
+                 Technician technician= (Technician) ServiceLocator.currentSession().load(Technician.class, new Long(technicianId));
+                 return technician;
+             }
+             catch (Exception e)
+             {
+                 throw new PersistenceException("Could not retrieve.", e);
+             }
+       }
+
+
+    public static List retrieveAllTechnicians() throws PersistenceException
+    {
+        if (allTechnicians == null)
+        {
+            try
+            {
+                Query q = ServiceLocator.currentSession().createQuery("from technician in class " + Technician.class +" order by upper(technician.name)");
+                allTechnicians = q.list();
+                session.flush();
+            }
+            catch (Exception e)
+            {
+                e.printStackTrace();
+                throw new PersistenceException(e);
+            }
+        }
+        return allTechnicians;
+
+    }
+
+
+}
+
+]]>
+      </source>
+      <p>
+          By using this TechnicianManager class, we could feasibly swap out the Hibernate code
+          for another OM strategy.  Even better would be to have a TechnicianManager interface
+          and a TechicianManagerImpl class.  Possibly loaded via Avalon as a component!
+      </p>
+    </section>
+
+    <section name="Setup PersitenceException handling">
+        <p>
+      By catching a generice Persistence Exception that wraps all the
+      thrown exceptions we can just catch a single exception and then
+      retrieve what type of exception it is.
+        </p>
+        <source>
+<![CDATA[
+package com.upstate.cellculture.om.persist;
+
+import org.apache.commons.lang.exception.NestableException;
+/**
+ * A general PersistenceException that is thrown by all Manager classes.
+ *
+ */
+public class PersistenceException extends NestableException
+{
+    //~ Constructors ===========================================================
+
+    /**
+     * Constructor for PersistenceException.
+     */
+    public PersistenceException()
+    {
+        super();
+    }
+
+    /**
+     * Constructor for PersistenceException.
+     *
+     * @param message
+     */
+    public PersistenceException(String message)
+    {
+        super(message);
+    }
+
+    /**
+     * Constructor for PersistenceException.
+     *
+     * @param message
+     * @param cause
+     */
+    public PersistenceException(String message, Throwable cause)
+    {
+        super(message, cause);
+    }
+
+    /**
+     * Constructor for PersistenceException.
+     *
+     * @param cause
+     */
+    public PersistenceException(Throwable cause)
+    {
+        super(cause);
+    }
+
+}
+
+]]>
+      </source>
+
+    </section>
+  </body>
+</document>
+
+
diff --git a/src/site/xdoc/howto/ide-vaj-wte-howto.xml b/src/site/xdoc/howto/ide-vaj-wte-howto.xml
new file mode 100644
index 00000000..e4ed2b59
--- /dev/null
+++ b/src/site/xdoc/howto/ide-vaj-wte-howto.xml
@@ -0,0 +1,149 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<document>
+  <header>
+    <title>VAJava and WebSphere Test Environment</title>
+  </header>
+
+  <body>
+
+    <section name="Forewords and Requirements">
+
+      <p>
+        This tutorial explains how to run Turbine within VisualAge for
+        Java WebSphere Test Environment.
+      </p>
+      <p>
+        This tutorial works with VAJava 3.5.2 and 3.5.3. Please tell us if you
+        find that it works with other versions.
+      </p>
+
+    </section>
+
+    <section name="Step 1 : Import the correct packages in VAJava">
+
+      <p>
+        Let's assume the following conventions :
+        <strong><code>{Turbine dir}</code></strong> is the directory where you
+        have unzipped the Turbine distribution or sources and
+        <strong><code>{VAJava dir}</code></strong> is the directory where
+        VAJava is installed. Let's also define <strong><code>{WTE dir}</code>
+        </strong> to be the WebSphere Test Environment directories, i.e.
+        <code>{VAJava dir}/ide/project_resources/IBM WebSphere Test
+        Environment</code>.
+      </p>
+
+      <p>
+        You need to create a project : Turbine
+      </p>
+
+      <p>
+        Import into Turbine project all JARS/SRC associated with the specific
+        Turbine release
+      </p>
+
+    </section>
+
+    <section name="Step 2 : Modify WebSphere Test Environment">
+
+      <section name="Edit default.servlet_engine">
+
+        <p>
+          Edit <code>{WTE dir}/properties/default.servlet_engine</code> and
+          add the following under the <code>default_app</code> webgroup :
+        </p>
+
+<source><![CDATA[
+    <websphere-webgroup name="turbine">
+       <description>Turbine Application Framework</description>
+       <document-root>$approot$/web</document-root>
+       <classpath>$approot$/servlets</classpath>
+       <root-uri>/turbine</root-uri>
+       <auto-reload enabled="true" polling-interval="3000"/>
+       <shared-context>false</shared-context>
+    </websphere-webgroup>
+]]></source>
+
+      </section>
+
+      <section name="Create a turbine directory">
+
+        <p>
+          Create a directory called <code>turbine</code> under
+          <code>{WTE dir}/hosts/default_host</code>. Under <code>turbine</code>
+          create another 2 subdirectories : <code>servlets</code> and
+          <code>web</code>.
+        </p>
+
+        <p>
+	Create the following directories (which is similiar to the TDK distribution)
+	under the web directory.
+	<li> images </li>
+	<li> logs </li>
+	<li> resources</li>
+	<li> stylesheets</li>
+	<li> templates</li>
+	<li> WEB-INF/conf</li>
+        </p>
+        <p>
+        Copy the TurbineResource.properties file to the "WEB-INF/conf" directory. The templates,
+        logs etc. directories are quite self explanetory I think.
+        </p>
+
+      </section>
+
+      <section name="Create a turbine.webapp file">
+
+        <p>
+          Create a <code>turbine.webapp</code> file in
+          <code>{WTE dir}/host/default_app/servlets</code> and put the following
+          content :
+<source><![CDATA[
+<webapp>
+   <name>turbine</name>
+   <description>Turbine Application Framework</description>
+   <error-page>/ErrorReporter</error-page>
+
+   <servlet>
+      <name>turbine</name>
+      <description>Turbine Application Framework</description>
+      <code>org.apache.turbine.Turbine</code>
+      <servlet-path>/ServletRedirector</servlet-path>
+      <autostart>true</autostart>
+   </servlet>
+ </webapp>
+]]></source>
+        </p>
+
+      </section>
+
+    </section>
+
+    <section name="Step 3 : Edit VAJava workspace classpath">
+
+      <p>
+        In the WebSphere Test Environment under Servlet Engine, add Turbine to the classpath.
+      </p>
+
+    </section>
+  </body>
+</document>
+
diff --git a/src/site/xdoc/howto/index.xml b/src/site/xdoc/howto/index.xml
new file mode 100644
index 00000000..155d7f12
--- /dev/null
+++ b/src/site/xdoc/howto/index.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<document>
+
+  <properties>
+    <title>Turbine</title>
+  </properties>
+
+  <body>
+
+  <section name="Howtos">
+    <p>
+      <ul>
+        <li><a href="action-event-howto.html">Action Events Howto</a></li>
+        <li><a href="annotations.html">Annotations Howto</a></li>
+        <li><a href="configuration-howto.html">Configuration Howto</a></li>
+        <li><a href="extend-user-howto.html">Extend User Howto</a></li>
+        <li><a href="/fulcrum/fulcrum-intake/howto.html">Intake Howto</a></li>
+        <li><a href="jsp-howto.html">JSP Howto</a></li>
+        <li><a href="migrate-from-2_1-howto.html">Migrating from 2.1 to 2.2</a></li>
+        <li><a href="migrate-from-2_2-howto.html">Migrating from 2.2 to 2.3</a></li>
+        <li><a href="migrate-from-2_3-howto.html">Migrating from 2.3 to 4.0</a></li>
+        <li><a href="migrate-from-4_0-howto.html">Migrating from 4.0 to 5.0</a></li>
+        <li><a href="pullmodel-howto.html">Pull Model Howto</a></li>
+        <li><a href="python-howto.html">Python Howto</a></li>
+        <li><a href="security-howto.html">Security Howto</a></li>
+        <li><a href="services-howto.html">Services Howto</a></li>
+        <li><strong>NEW!</strong> <a href="url-mapper-howto.html">URL Mapper Howto</a></li>
+        <li><a href="url-rewriting-howto.html">URL Rewriting Howto</a></li>
+        <li><a href="context-howto.html">Velocity Context Howto</a></li>
+        <li><a href="velocity-site-howto.html">Velocity Site Howto</a></li>
+        <li><a href="velocityonlylayout-howto.html">VelocityOnlyLayout Howto</a></li>
+        <li><a href="hibernate-howto.html">Hibernate OM Howto</a></li>
+      </ul>
+    </p>
+  </section>
+
+  </body>
+</document>
diff --git a/src/site/xdoc/howto/intake-howto.xml b/src/site/xdoc/howto/intake-howto.xml
new file mode 100644
index 00000000..c06d6381
--- /dev/null
+++ b/src/site/xdoc/howto/intake-howto.xml
@@ -0,0 +1,551 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<document>
+
+    <properties>
+        <title>"Simple" Intake How-to for Turbine 2.1</title>
+    </properties>
+
+    <body>
+        <section name="Introduction">
+            <p>
+                First of all I'd like to note that this document is based on my
+                experience in using Intake for Turbine 2.1.  I've tried to make
+                it as correct as possible but I don't guarantee anything.  This
+                has been written as a guide for a new Intake user and assumes
+                some familiarity with Turbine 2.1.
+            </p>
+            <p>
+                To use intake, the following steps are required:
+
+                <ol>
+                    <li>Create your turbine template with a form.</li>
+                    <li>Create the intake.xml file.</li>
+                    <li>Create a business object to represent the intake group
+                        we are working with (this is optional).</li>
+                    <li>Create the Turbine Action to handle the form
+                        submission.</li>
+                </ol>
+            </p>
+            <p>
+                Some additional information concerning removing Intake group
+                information from the request is included at the bottom of this
+                document.
+            </p>
+        </section>
+
+        <section name="Step 1: Create your turbine template with a form">
+            <p>
+                The first thing to do is the create the form in your template
+                (e.g. a velocity template file, a .vm file).  Just create the
+                skeleton structure and don't worry about the field names and
+                values yet.  Note that field names will have to match the names
+                specified in the intake.xml file.  Actually you can do the
+                opposite (name the fields here first and match them in the
+                intake.xml file) if you wish, but this guide will do it the
+                former way.
+            </p>
+            <p>
+                Now add the following lines above the code for your form and
+                modify it to match the group and field names in your intake.xml
+                file (perhaps you can come back to do this step after you've
+                done your intake.xml file).  Here is an example in a Velocity
+                template for a "login form":
+            </p>
+            <source><![CDATA[
+#set($loginGroup = $intake.LoginGroup.Default)
+            ]]></source>
+            <p/>
+            <p>
+                What this does is to set a Velocity variable called $loginGroup
+                to a default group object specified by intake.xml.  The $intake
+                variable is the Turbine Pull Tool instance (IntakeTool).  The
+                "LoginGroup" is the name of the group as specified in the
+                intake.xml file (names must match, and this is not the group's
+                key attribute.).  The "Default" part obtains a generic default
+                intake group object. Or in other words, this resolves to
+                IntakeTool.get(String groupName) with the groupName being
+                "LoginGroup".  Also, you can re-write the statement as
+                $intake.get("LoginGroup").getDefault() in your template.
+            </p>
+            <p>
+                Or if you would like to map the intake group to a business
+                object (for whatever purpose) then you can do this (read on
+                for more info on what is required to do this in intake.xml and
+                the corresponding Turbine Action class):
+            </p>
+            <source><![CDATA[
+#set($loginGroup = $intake.LoginGroup.mapTo($mytool.getInstanceLoginForm()))
+            ]]></source>
+            <p/>
+            <p>
+                What this does is to set a Velocity variable called $loginGroup
+                to an instance of the LoginForm business object (and if the
+                returned object has values in its fields and appropriate
+                "getter" methods then this would prepopulate the intake group
+                with the values.  A good usage example of this is when you
+                would like to prepopulate the form with values from the
+                database and want to use intake to validate the form).  It
+                makes use of a custom tool placed into the Velocity context as
+                "$mytool" (you can make your own tool to instantiate an instance
+                of your business object similar to this example).
+            </p>
+            <p>
+                So, depending on the method you use above, the corresponding
+                Turbine Action code will need to "cooperate" accordingly.
+                We'll discuss this later in step 4.
+            </p>
+            <p>
+                Near the end of the form (before you close the "form" tag)
+                include the following line:
+            </p>
+            <source><![CDATA[
+$intake.declareGroups()
+            ]]></source>
+            <p/>
+            <p>
+                What this does is to fill in hidden form fields into the form
+                for use by intake.
+            </p>
+            <p>
+                In order to use Turbine's Action event system, the submit buttons
+                must adhere to the naming specification defined by
+                <a href="http://turbine.apache.org/turbine-2/howto/action-event-howto.html">
+                Turbine's Action event system</a>.
+            </p>
+
+            <subsection name="*** IMPORTANT NOTE ***">
+                <p>
+                    If you use
+                    $link.setAction('SomeAction').setPage('NextTemplate.vm')
+                    in your form's action attribute like this:
+                </p>
+                <source><![CDATA[
+<form name="myForm" method="POST"
+      action="$link.setAction('LoginAction').setPage('NextTemplate.vm')">
+    ...
+</form>
+                ]]></source>
+                <p/>
+                <p>
+                    then the form validation won't appear to work (i.e. the user
+                    will see the NextTemplate.vm file instead of the form they
+                    were trying to fill out which failed validation).  To work
+                    around this problem, you can omit the setPage('...') part
+                    in your form's action attribute and then have your action
+                    route the user to the next template on validation success
+                    OR somehow detect the current form the user is at and if
+                    the validation fails, override the next template to the
+                    current template (which is really just overriding the
+                    setPage() part in the template file specified by the web
+                    designer).
+                </p>
+            </subsection>
+        </section>
+
+        <section name="Step 2: Create the intake.xml file">
+            <p>
+                The intake.xml file specifies the validation rules required to
+                be satisfied in order for the form to be accepted.  The file has
+                a "root" XML element of "input-data" and in that would be
+                "group" elements.
+            </p>
+            <p>
+                Here is an example of the element (with no other sub-elements):
+            </p>
+            <source><![CDATA[
+<!DOCTYPE input-data SYSTEM
+           "http://turbine.apache.org/dtd/intake_2_3.dtd">
+<input-data basePackage="ca.yorku.devteam.inca.clients.skeleton.">
+    ...group elements goes here...
+</input-data>
+            ]]></source>
+            <p/>
+            <p>
+                Notice the basePackage attribute (optional) points to the
+                skeleton package with an extra period at the end.  This
+                attribute specifies the package that contains the java objects
+                the "group" and "field" elements can optionally map to.
+                The trailing period is REQUIRED.
+            </p>
+
+            <subsection name="&lt;group&gt; elements">
+                <p>
+                    Each group element represents a collection of field information you'd like to
+                    validate in your form.  For example, on a login page you would have a form for
+                    the user to input their username and password, and as well as a login button.
+                    This entire form would be grouped as a group in the intake.xml file.
+                </p>
+                <p>
+                    Here is an example of a group with no other elements (not useful yet):
+                </p>
+                <source><![CDATA[
+<group name="LoginGroup" key="loginGroupKey" mapToObject="LoginForm">
+    ...field elements goes here...
+</group>
+                ]]></source>
+                <p/>
+                <p>
+                    A group element can have the following attributes:
+
+                    <ul>
+                        <li>"name" attribute
+                            <ul>
+                                <li>
+                                    the name of the group, is required, and must
+                                    be unique across the entire intake.xml file.
+                                </li>
+                            </ul>
+                        </li>
+                    </ul>
+
+                    <ul>
+                        <li>"key" attribute
+                            <ul>
+                                <li>
+                                    the key of the group, is required, and must
+                                    be unique across the entire intake.xml file.
+                                </li>
+                            </ul>
+                        </li>
+                    </ul>
+
+                    <ul>
+                        <li>"mapToObject" attribute
+                            <ul>
+                                <li>
+                                    optional, used if you want to map the form
+                                    to a business object. Note that the field
+                                    names specified later by the "field" element
+                                    in the group should match the field names of
+                                    the business object with appropriate get/set
+                                    methods.  See the "field" tag examples to
+                                    find how to override this default behaviour.
+                                </li>
+                            </ul>
+                        </li>
+                    </ul>
+                </p>
+                <p>
+                    For a complete list of valid attributes of the group
+                    element, please see the
+                    <a href="http://turbine.apache.org/turbine-2/services/intake-service.html">
+                    intake-service document</a> on the Turbine web site.
+                </p>
+            </subsection>
+
+            <subsection name="&lt;field&gt; elements">
+                <p>
+                    Each group element can contain any number of "field"
+                    elements.  Each field element will correspond to a field in
+                    the form.  The name and key of each field will be used in
+                    the form code in the template so make sure the names and
+                    keys match in both files (intake.xml and the template file).
+                </p>
+                <p>
+                    Here is an example of a field with no other elements (not
+                    too useful yet):
+                </p>
+                <source><![CDATA[
+<field name="Username" key="loginUsernameKey" type="String"
+        mapToProperty="Username">
+    ...rule elements goes here...
+</field>
+                ]]></source>
+                <p/>
+                <p>
+                    A field element can have the following attributes:
+
+                    <ul>
+                        <li>"name" attribute
+                            <ul>
+                                <li>
+                                    the name of the field, is required, and must
+                                    be unique across the entire group element.
+                                </li>
+                            </ul>
+                        </li>
+                    </ul>
+
+                    <ul>
+                        <li>"key" attribute
+                            <ul>
+                                <li>
+                                    the key of the field, is required, and must
+                                    be unique across the entire group element.
+                                </li>
+                            </ul>
+                        </li>
+                    </ul>
+
+                    <ul>
+                        <li>"type" attribute
+                            <ul>
+                                <li>
+                                    required, the type of the field so that
+                                    intake will know what to expect.  Valid
+                                    types I know of are: String, Integer (I
+                                    believe these map to the corresponding Java
+                                    types).  Please see the intake.dtd for the
+                                    allowed values.
+                                </li>
+                            </ul>
+                        </li>
+                    </ul>
+
+                    <ul>
+                        <li>"mapToProperty" attribute
+                            <ul>
+                                <li>
+                                    optional, used if you want to map the form
+                                    to a business object.  Note that the field
+                                    names specified in this "field" element
+                                    should match the field name of the business
+                                    object with appropriate get/set methods.
+                                </li>
+                            </ul>
+                        </li>
+                    </ul>
+                </p>
+                <p>
+                    For a complete list of valid attributes of the field
+                    element, please see the
+                    <a href="http://turbine.apache.org/turbine-2/services/intake-service.html">
+                    intake-service document</a> on the Turbine web site.
+                </p>
+            </subsection>
+
+            <subsection name="&lt;rule&gt; elements">
+                <p>
+                    In each field element, you can have rules defined.  The
+                    supported rule elements for Intake in Turbine 2.1 are:
+                </p>
+                <source><![CDATA[
+<rule name="required" value="true">Error message for required failed</rule>
+<rule name="minLength" value="4">Error message for required min length failed</rule>
+<rule name="maxLength" value="9">Error message for required max length failed</rule>
+<rule name="mask" value="^[0-9]+$">Error message for regular expression failed</rule>
+<rule name="notANumberMessage">Error message for Number fields when the entry is not a number</rule>
+
+                ]]></source>
+                <p/>
+                <p>
+                    For more info on the supported rules, please see the
+                    <a href="http://turbine.apache.org/turbine-2/services/intake-service.html">
+                    intake-service document</a> on the Turbine web site:
+                </p>
+            </subsection>
+        </section>
+
+        <section name="Step 3: Create a business object to represent the intake group we are working with (this is optional).">
+            <p>
+                The business object is basically a Java class that has get and
+                set methods for each of the object's fields, and these get and
+                set method names should match the field names specified in the
+                intake.xml file (whether we stay with the default behaviour of
+                matching the field names in intake.xml and the business object
+                or we use the mapToProperty attribute in the "field" element).
+                Note it is required to use the mapToObject property in the group
+                element to use this feature.
+            </p>
+            <p>
+                The business object also has to implement the
+                org.apache.turbine.om.Retrievable interface.  The Retrievable
+                was designed to work with a database so the methods
+                get/setQueryKey doesn't make much sense if your business object
+                isn't based on a database model.  For my use, I just force the
+                key to be "_0" which is the default key used by Intake (as of
+                Turbine 2.1).  You could, of course, implement it as a normal
+                data field to allow the template to set the query key and then
+                in the Action to get the query key.  But then you'll have to
+                keep track of the key you use in both the template file and
+                Action class (the benefit would be that you'll be able to use
+                more than 1 business object in the same template if you get/set
+                the different query keys).
+            </p>
+            <p>
+                Here is an example of how to use the setQueryKey() and
+                getQueryKey() methods of the business object that implements
+                the Retrievable interface:
+            </p>
+            <p>
+                In the template file, e.g. myform.vm:
+            </p>
+            <source><![CDATA[
+#set($loginForm = $mytool.getLoginFormInstance())
+$loginForm.setQueryKey("abc")
+#set($loginGroup = $intake.LoginGroup.mapTo($loginForm))
+            ]]></source>
+            <p/>
+            <p>
+                In the Action class:
+            </p>
+            <source><![CDATA[
+// This key has to match the one in the template
+String key = "abc";
+Group group = intake.get("LoginGroup", key);
+            ]]></source>
+            <p/>
+        </section>
+
+        <section name="Step 4: Create the Turbine Action to handle the form submission.">
+            <p>
+                Depending on the method you use, the code in the action will
+                need to obtain the corresponding group object from intake.  The
+                following examples will demonstrate the ideas.
+            </p>
+            <p>
+                Here is an example the code in a Turbine Action, using intake
+                without mapping to a business object (vanilla method):
+            </p>
+            <source><![CDATA[
+/**
+ * Performs user login
+ */
+public void doLogin(RunData data, Context context)
+        throws Exception {
+    // Get intake group
+    IntakeTool intake =
+            (IntakeTool)context.get("intake");
+
+    // Notice how this gets the group named "LoginGroup" as defined in
+    // the intake.xml file, and gets it using the default key
+    // IntakeTool.DEFAULT_KEY (which is "_0").
+    Group group = intake.get("LoginGroup", IntakeTool.DEFAULT_KEY);
+
+    // Check if group fields are valid and if they are not, then return.
+    // Intake will handle the validation error and display the
+    // corresponding error messages to the user but if you use the setPage()
+    // mechanism to get the "next template" then you must now set the
+    // template to be the same one as the user was filling out.  Otherwise
+    // the user will just see the next template.  See the "important note"
+    // in step 1.
+    if (!group.isAllValid()) {
+        Log.debug("Group elements INVALID");
+        setTemplate(data, "Login.vm");
+        return;
+    } else {
+        // If all is validated then you can set the next template and/or
+        // continue processing...it's up to you.  You can also use
+        // setPage() in the template file to set the next template to show
+        // on successful validation.
+        setTemplate(data, "LoginSuccess.vm");
+    }
+
+    // This gets the value of the "Username" field from the group object
+    String username = (String)group.get("Username").getValue();
+    String password = (String)group.get("Password").getValue();
+
+    // Now you will be able to use the username and password variable in
+    // the rest of the Turbine Action.
+    ...
+}
+            ]]></source>
+            <p/>
+            <p>
+                Here is example code in a Turbine Action, using the intake
+                group's default mapToObject setting (this is the same whether
+                or not you use the field's mapToProperty attribute):
+            </p>
+            <source><![CDATA[
+/**
+ * Performs user login
+ */
+public void doLogin(RunData data, Context context)
+        throws Exception {
+    // Get intake group
+    IntakeTool intake =
+            (IntakeTool)context.get("intake");
+    Group group = intake.get("LoginGroup", IntakeTool.DEFAULT_KEY);
+
+    // Check if group fields are valid and if they are not, then return.
+    // Intake will handle the validation error and display the
+    // corresponding error messages to the user but if you use the setPage()
+    // mechanism to get the "next template" then you must now set the
+    // template to be the same one as the user was filling out.  Otherwise
+    // the user will just see the next template.  See the "important note"
+    // in step 1.
+    if (!group.isAllValid()) {
+        Log.debug("Group elements INVALID");
+        setTemplate(data, "Login.vm");
+        return;
+    } else {
+        // If all is validated then you can set the next template and/or
+        // continue processing...it's up to you.  You can also use
+        // setPage() in the template file to set the next template to show
+        // on successful validation.
+        setTemplate(data, "LoginSuccess.vm");
+    }
+
+    // Instaniate a business object that represents the form
+    LoginForm loginForm = new LoginForm();
+
+    // Set the properties of the form given the field data in the group
+    // (i.e. populate the business object)
+    group.setProperties(loginForm);
+
+    // Now the business object is populated accordingly.  You can use it
+    // for whatever purpose in the rest of the Turbine Action.
+    ...
+}
+            ]]></source>
+            <p/>
+        </section>
+        <section name="Removing Intake information from the request">
+            <p>
+                Intake data is retained in the request in order to allow for the
+                possibility that it will be re-presented to the user on the next
+                page. Normally this is desirable behaviour - there may have been
+                an error in the data so you want to redisplay it. There is a
+                possibility however that you might want to reuse the same group
+                on either the same or a different page after fully processing
+                the data; in this case it may be undesirable to redisplay the
+                previously entered data. The prime example of this is where a
+                page includes a repeating group of records and provides an
+                opportunity to add a further record using the default group,
+                returning to the same page after each record is added.  In this
+                situation you will find that the default group needs to be
+                removed from the request, otherwise the data entered on the
+                previous page will be redisplayed.
+            </p>
+            <p>
+                Intake allows for this by providing a way of removing the data
+                that is no longer appropriate to display.  Simply:
+            </p>
+            <source><![CDATA[
+intake.remove(group);
+            ]]></source>
+            <p/>
+            <p>
+                ... where "intake" is a reference to your IntakeTool and "group"
+                is a reference to the group you wish to remove from the
+                request.  You would do this after the new record had been
+                validated and added to the database.
+            </p>
+            <p>
+                It will be rare that you actually need to do this - it is
+                required only in situations where the same group is used on
+                subsequent pages after the data has been fully processed (it
+                should be pretty obvious when this is the case).
+            </p>
+        </section>
+    </body>
+</document>
diff --git a/src/site/xdoc/howto/jboss-howto.xml b/src/site/xdoc/howto/jboss-howto.xml
new file mode 100644
index 00000000..9b148b46
--- /dev/null
+++ b/src/site/xdoc/howto/jboss-howto.xml
@@ -0,0 +1,127 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<document>
+
+ <properties>
+   <title>JBoss Howto</title>
+ </properties>
+
+ <body>
+
+ <section name="3 Steps to get the Catalina included with TDK to work with JBoss2.2.1">
+ <p>
+ Comment 2006-06-20: This is so unbelievably old (we no longer produce the TDK
+ and JBoss is now at version 4.0.x).
+ </p>
+
+ <p>
+ By: <a href="mailto:john NOSPAM murphyfutures.com">John Menke</a><br/>
+ </p>
+
+ <p>
+    <ol>
+    <li>Edit the startup.sh:
+    <p>
+    $BASEDIR/catalina.sh run -nonaming "$@"  (-nonaming does not work with start)
+    </p>
+    </li>
+    <li>
+    Move all the files from JBOSS_HOME/client directory to the /WEB-INF/lib
+    directory.
+    </li>
+    <li>
+    Delete the jndi.jar file (and the jndi-1.2.1.jar) from the /WEB-INF/lib
+    directory.
+    </li>
+    </ol>
+  </p>
+  <p>
+  I probably have extra jars in the WEB-INF/lib at the moment, but IT WORKS!
+  </p>
+
+<source>
+WEB-INF/lib
+	TestBeanClient.jar
+	activation-1.01.jar
+	connector.jar
+	deploy.jar
+	ecs-1.4.1.jar
+	ejb.jar
+	hsql.jar
+	jaas.jar
+	jakarta-regexp-1.3-dev.jar
+	jboss-client.jar
+	jbossmq-client.jar
+	jbosssx-client.jar
+	jdbc-se2.0.jar
+	jdbc2_0-stdext.jar
+	jnp-client.jar
+	jta-spec1_0_1.jar
+	jta1.0.1.jar
+	junit-3.2.jar
+	log4j-1.0.4.jar
+	mail-1.2.jar
+	mm.mysql-2.0.4.jar
+	postgresql.jar
+	stop.jar
+	turbine-2.1-dev-unrealeased.jar
+	velocity-1.0b2-dev.jar
+	village-1.5.1-dev.jar
+	xalan-1.2.1.jar
+	xerces-1.3.0.jar
+	xmlrpc.jar
+</source>
+
+  <p>
+  THIS EXAMPLE JNDI CODE NOW RUNS: (servlet from within TDK)
+  </p>
+
+<source><![CDATA[
+try
+{
+    // Set up the naming provider. This may not always be necessary,
+    // depending on how your Java system is configured.
+    System.setProperty("java.naming.factory.initial",
+      "org.jnp.interfaces.NamingContextFactory");
+    System.setProperty("java.naming.provider.url",
+      "localhost:1099");
+    // Get a naming context
+    InitialContext jndiContext = new InitialContext();
+
+    // Get a reference to the Interest Bean
+    Object ref = jndiContext.lookup("interest/Interest");
+
+    // Get a reference from this to the Bean's Home interface
+    InterestHome home = (InterestHome)
+        PortableRemoteObject.narrow (ref, InterestHome.class);
+
+    // Create an Interest object from the Home interface
+    m_interest = home.create();
+}
+catch(Exception e)
+{
+    out.println("<LI>Context failed: " + e);
+}
+]]></source>
+</section>
+
+ </body>
+</document>
diff --git a/src/site/xdoc/howto/jsp-howto.xml b/src/site/xdoc/howto/jsp-howto.xml
new file mode 100644
index 00000000..175632da
--- /dev/null
+++ b/src/site/xdoc/howto/jsp-howto.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<document>
+
+ <properties>
+  <title>JSP Howto</title>
+ </properties>
+
+<body>
+
+<section name="JSP + Turbine Configuration">
+
+<p>
+It is quite possible to use JSP with Turbine. In order to do so, you
+need to tweak the existing configuration in the
+TurbineResources.properties file as described below. This is an evolving
+document, if there are still errors in this configuration, <a
+href="http://turbine.apache.org/contact.html">please subscribe to the
+Turbine Users list and let us know</a>. Also note that this file is
+checked into Turbine's CVS tree under xdocs/jsp-configuration.xml. We
+appreciate all <a
+href="https://issues.apache.org/jira/browse/TRB">patches and
+contributions</a> that improve this document.
+</p>
+
+<p>
+In TurbineResources.properties, search for the key values and
+modify/verify the following settings:
+</p>
+
+<source><![CDATA[
+template.homepage=/index.jsp (or whatever jsp you want for the start
+                              page)
+
+template.login=/login.jsp    (or whatever jsp you want for the login
+                              form)
+
+page.default=JspPage
+
+services.JspService.classname=org.apache.turbine.services.jsp.TurbineJspService
+]]></source>
+
+<p>
+If you want to use "complete" JSP pages (rather than using Turbine's
+model of having separate files for the navigation components, etc.),
+then you must set the JspService.default.layout entry so that
+DefaultLayout is used:
+</p>
+
+<source><![CDATA[
+services.JspService.default.layout = DefaultLayout
+]]></source>
+
+<p>
+Place JSP pages in the &lt;app&gt;/templates/app/screens directory.
+</p>
+
+<p>
+Refer to the JSP pages in URLs as .../template/app/&lt;xxx&gt;.jsp
+</p>
+
+</section>
+
+</body>
+</document>
diff --git a/src/site/xdoc/howto/ldap-howto.xml b/src/site/xdoc/howto/ldap-howto.xml
new file mode 100644
index 00000000..b8d7c0ea
--- /dev/null
+++ b/src/site/xdoc/howto/ldap-howto.xml
@@ -0,0 +1,189 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<document>
+
+ <properties>
+   <title>LDAP Howto</title>
+ </properties>
+
+ <body>
+
+ <section name="LDAP Details">
+  <p>
+These are the details on how we came up with this schema for
+putting the user-group-permission tables in an LDAP directory. We want to
+start with the fact that for the schema proposed we have taken all new
+objectClasses and Attributes preceded by turbine to indicate that they are
+Turbine specific. We have thought about using the standard and available
+LDAP objectClasses and atributes, but finally decided to start the
+discussion with the turbine stuff.
+</p>
+<p>
+We also had to make some assumptions regarding the present use of the
+user-group-permission tables. This gave us the following schema:
+  </p>
+ </section>
+ <section name="Schema">
+<source>
+-- Attribute types --
+
+( 1000.1.1
+  NAME 'turbineGroupMember'
+  DESC ''
+  EQUALITY caseIgnoreMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
+)
+
+( 1000.1.2
+  NAME 'turbineObjectData'
+  DESC ''
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.40
+)
+
+( 1000.1.3
+  NAME 'turbinePermission'
+  DESC ''
+  EQUALITY caseIgnoreMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+)
+
+( 1000.1.4
+  NAME 'turbineRoleMember'
+  DESC ''
+  EQUALITY caseIgnoreMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
+)
+
+( 1000.1.5
+  NAME 'turbineUserCreationDate'
+  DESC ''
+  EQUALITY caseIgnoreMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.53
+  SINGLE-VALUE
+)
+
+( 1000.1.6
+  NAME 'turbineUserFirstName'
+  DESC ''
+  EQUALITY caseIgnoreMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+)
+
+( 1000.1.7
+  NAME 'turbineUserLastLogon'
+  DESC ''
+  EQUALITY caseIgnoreMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.53
+  SINGLE-VALUE
+)
+
+( 1000.1.8
+  NAME 'turbineUserLastModifiedTime'
+  DESC ''
+  EQUALITY caseIgnoreMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.53
+  SINGLE-VALUE
+)
+
+( 1000.1.9
+  NAME 'turbineUserLastName'
+  DESC ''
+  EQUALITY caseIgnoreMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+)
+
+( 1000.1.10
+  NAME 'turbineUserMailAddress'
+  DESC ''
+  EQUALITY caseIgnoreIA5Match
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+)
+
+( 1000.1.11
+  NAME 'turbineUserPassword'
+  DESC ''
+  EQUALITY caseExactMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+  SINGLE-VALUE
+)
+
+( 1000.1.12
+  NAME 'turbineUserUniqueId'
+  DESC ''
+  EQUALITY caseIgnoreMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+  SINGLE-VALUE
+)
+-- Object classes --
+
+( 1000.2.1
+  NAME 'turbineGroup'
+  DESC 'Turbine group'
+  SUP top
+  AUXILIARY
+  MAY ( turbineGroupMember $ turbineObjectData )
+)
+
+( 1000.2.2
+  NAME 'turbineRole'
+  DESC 'Turbine role'
+  SUP top
+  AUXILIARY
+  MAY ( turbineObjectData $ turbinePermission $ turbineRoleMember )
+)
+
+( 1000.2.3
+  NAME 'turbineUser'
+  DESC 'Turbine user'
+  SUP top
+  AUXILIARY
+  MUST ( turbineUserUniqueId )
+  MAY ( turbineObjectData $ turbineUserCreationDate $ turbineUserFirstName $
+turbineUserLastLogon $ turbineUserLastModifiedTime $ turbineUserLastName $
+turbineUserMailAddress $ turbineUserPassword )
+)
+</source>
+ </section>
+<section name="More Details">
+<p>
+We have turbineRole that can have many turbinePermission entries. These
+are DN pointing to the turbinePermission objects. turbineUser will hold
+all user related information. turbineGroup can hold in the
+turbineGroupMember DNs of turbineUser objects. Thus having multiple
+users being member of a group. There is however no relation with role at
+this stage. The releation role - user is stored in the turbineRole
+having multiple DNs in turbineRoleMember. Then we have a user - role
+relation thus giving user permission via roles they can perform. There
+is no relation between role - user - group in one record. This could be
+possible with the DB model, but we could you put this dependancy in the
+hierarchical structure of a directory. With the separate user - role and
+user - group relations we thought we'd have the most desired relations.
+</p>
+<p>
+Please note that the Object Identifiers (OID) in this example are not
+real ones. When we go for the turbine objectClasses and attributes
+Turbine (or Apache) have to register (if they not already have) their
+own OID starting point in the IANA tree. We are fully open for dicussion
+and appreciate your feedback on the mailing list.
+</p>
+</section>
+ </body>
+</document>
diff --git a/src/site/xdoc/howto/migrate-from-2_1-howto.xml b/src/site/xdoc/howto/migrate-from-2_1-howto.xml
new file mode 100644
index 00000000..497ddaaa
--- /dev/null
+++ b/src/site/xdoc/howto/migrate-from-2_1-howto.xml
@@ -0,0 +1,373 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<document>
+
+ <properties>
+  <title>Migrating from 2.1 to 2.2</title>
+ </properties>
+
+<body>
+
+<section name="Important note">
+<p>
+    The information in this HOWTO pertains to Turbine 2.2.  Please refer
+    to the <a href="migrate-from-2_2-howto.html">Migrating from
+    2.2 to 2.3</a> page for information on migating to Turbine 2.3.
+</p>
+</section>
+
+<section name="Introduction">
+<p>
+    This document describes the basic steps needed to migrate an
+    application written for Turbine 2.1 to Turbine 2.2 using the
+    decoupled Torque.
+</p>
+<p>
+    You may find that migrating to 2.2 is not all that difficult.
+    Of course, this depends quite a bit on how much of Turbine your
+    application actually uses.  You may find migrating to 2.2 to be
+    quite a chore, but it is well worth the effort. Most of the
+    pain in figuring out this migration process has been documented
+    in the mailing list archives, but is summarized here for your
+    convenience.
+</p>
+</section>
+
+<section name="Cleanup">
+<p>
+    Start off with deleting all of the objects that Torque generated
+    for you. I am talking about om.map.* and om.Base*. You will be
+    able to regenerate them later during the migration process.
+</p>
+</section>
+
+<section name="Build and Properties Files">
+<p>
+    The structure of the build files used by Turbine has changed
+    quite a bit with the 2.2 release. The easiest way of obtaining
+    a reference set of property (and build files) is to install
+    version 2.2 of the TDK and generate the demo application.
+</p>
+<p>
+    From the demo application you should:
+    <ul>
+    <li>Merge <code>tdk-2.2/webapps/newapp/WEB-INF/conf/build.properties</code>
+        with your existing properties file.</li>
+    <li>Copy <code>build-torque.xml</code> from the demo application
+        to your build directory.</li>
+    <li>Copy <code>project-build.xml</code> from the demo application
+        to your build directory.</li>
+    <li>Merge <code>build.xml</code> from the demo application
+        to your existing build file (if you have only ever used the
+        default build file supplied with the tdk then I assume you
+        can just replace your file with the new one).</li>
+    <li>Copy <code>WEB-INF/conf/TurbineResources.template</code> and
+        <code>WEB-INF/conf/Torque.template</code>) to your application
+        and apply changes as needed (it is up to you as to how much you
+        hard code into your application template and how much you allow
+        to be processed into the resulting properties files by way of
+        <code>build.properties</code> or the other property files).</li>
+    </ul>
+</p>
+<p>
+    See the Torque
+  <a href="http://db.apache.org/torque/properties-reference.html">
+    Properties Reference</a> for full details of the available properties.
+</p>
+</section>
+
+<section name="Libraries">
+<p>
+    Turbine and Torque use updated versions of a number of
+    libraries (jar files). Take a look at the WEB-INF/lib directory
+    of the TDK sample application to see which libraries have been
+    updated and replace the files in the lib directory of your
+    application as needed.
+</p>
+<p>
+    Note that if you have applied local changes to Turbine itself
+    then you should ensure that your changes have made it into the
+    Turbine 2.2 and Torque 3.0 releases.  If any of your changes
+    have not made it then you will need to port these changes forward
+    and build your own versions of the Turbine and Torque jar files
+    (while you are there you may as well create patches and submit
+    them to the relevant modules in Scarab so that they can be
+    included in future releases).
+</p>
+<p>
+    By default Torque will utilize a set of  Velocity templates that
+    you need to extract from the Torque jar file (see the
+    <code>torque.templatePath</code> property). Unless you have a
+    need to alter these templates you may prefer to use these directly
+    from the jar file.  To do this you need to set the
+    <code>torque.useClasspath</code> property to <code>true</code> in
+    <code>build.peoperties</code>.  In any case, you should either
+    replace or delete the old versions of these templates from your
+    existing project.
+</p>
+</section>
+
+<section name="Import Statements">
+<p>
+    Many of your import statements will need to be changed. This is
+    due to the decoupled version of Torque. This will take care of
+    most of the changes due to refactoring. There will still be a
+    few cases (discussed later) where the methods have been changed and/or
+    moved to different classes.
+</p>
+<p>
+    <a href="http://db.apache.org/torque/changes.html#Torque%203.0-b3">
+    [Here]</a> is list of the most common import changes.
+</p>
+</section>
+
+<section name="Transactions and obtaining database connections">
+<p>
+    org.apache.turbine.util.db.DBConnection is gone. The replacement
+    is java.sql.Connection. This was a wrapper class from the
+    Connection object. It was returned when you asked for a database
+    connection. The new version of Torque will simply return a
+    Connection object.
+</p>
+<p>
+    org.apache.turbine.services.db.TurbineDB is gone. The replacement
+    is org.apache.torque.Torque. This was mainly used to obtain
+    database connections and the name of the default database. All
+    of this functionality is in the new class.
+</p>
+<p>
+    Below is an example of how you might have been obtaining database
+    connections in version 2.1.
+</p>
+
+<source>
+<![CDATA[
+DBConnection dbConn = null;
+try
+{
+    dbConn = TurbineDB.getConnection();
+    // Do something with the connection here...
+}
+catch (Exception e)
+{
+    // Either from obtaining the connection or from your application code.
+}
+finally
+{
+    try
+    {
+        TurbineDB.releaseConnection(dbConn);
+    }
+    catch (Exception e)
+    {
+        // Error releasing database connection back to pool.
+    }
+}
+]]>
+</source>
+<p>
+    Using the new version of Torque this would be rewritten as follows.
+</p>
+<source>
+<![CDATA[
+Connection conn = null;
+try
+{
+    conn = Torque.getConnection();
+    // Do something with the connection here...
+}
+catch (TorqueException ex)
+{
+    // Either from obtaining the connection or from your application code.
+	Log.error(ex);
+}
+finally
+{
+    Torque.closeConnection(conn);
+}
+]]>
+</source>
+<p>
+    Support for transactions has been moved from org.apache.turbine.om.BasePeer
+    into org.apache.torque.util.Transaction. The method names have changed
+    slightly as well. Here is an example of using transactions in 2.1.
+</p>
+<source>
+<![CDATA[
+DBConnection dbConn = null;
+try
+{
+    dbConn = BasePeer.beginTrasaction(TurbineDB.getDefaultDB?());
+    someObject.save(dbConn);
+    someOtherObject.save(dbConn);
+    BasePeer.commitTransaction(dbConn);
+}
+catch (Exception e)
+{
+    // Either from obtaining the connection or from your application code.
+    BasePeer?.rollbackTransaction(dbConn);
+}
+]]>
+</source>
+<p>
+    This would now be written as shown below.
+</p>
+<source>
+<![CDATA[
+Connection conn = null;
+try
+{
+    conn = Transaction.begin(Torque.getDefaultDB());
+    someObject.save(conn);
+    someOtherObject.save(conn);
+    Transaction.commit(conn);
+}
+catch (TorqueException ex)
+{
+    try
+    {
+        Transaction.rollback(conn);
+    }
+    catch (TorqueException ex2)
+    {
+        Log.error(ex2);
+    }
+    Log.error(ex);
+}
+]]>
+</source>
+</section>
+
+<section name="Vector becomes List">
+<p>
+    Methods generated by Torque that previously had a return type of
+    <code>Vector</code> now have a return type of <code>List</code>.
+    If you have not already been doing so you should switch to
+    retrieving the results of these methods into variables declared
+    as <code>List</code>.  While you are at it you might like to
+    update any of your own code to use <code>ArrayList</code> in
+    preference to <code>Vector</code>.
+</p>
+</section>
+
+<section name="Exception becomes TorqueException">
+<p>
+    Methods generated by Torque now throw <code>TorqueException</code>
+    rather than <code>Exception</code>.  You might like to update
+    your code to match.
+</p>
+<p>
+    Note that the exception thrown by <code>save()</code> methods is
+    determined by the Torque property <code>torque.saveException</code>
+    which defaults to <code>Exception</code>.
+</p>
+</section>
+
+<section name="Extending Turbine User">
+<p>
+    See
+    <a href="http://turbine.apache.org/turbine-2/howto/extend-user-howto.html">
+    Extending Turbine User How-To</a> for this information.
+</p>
+</section>
+
+<section name="Changes to the OM classes">
+<p>
+    Read over the Torque Schema Reference to find out what to change
+    in your project-schema.xml file. The main changes are the
+    deprecation of sequence and autoIncrement idMethods and the
+    addition of the javaType attribute to column elements
+    (Torque can now work with object types).
+</p>
+<p>
+    If you used inheritance, you will run need to specify
+    abstract="true" for the tables which have abstract base
+    classes. When you do this, you will need to implement the
+    copy() method in your subclasses. An example is provided below.
+</p>
+<source>
+<![CDATA[
+public <base class> copy() throws TorqueException
+{
+    return copyInto(new <sub class>());
+}
+]]>
+</source>
+<p>
+    Atributes defined as primary keys are no longer generated
+    as NumberKey objects. They are now Integer or int (depending
+    on the javaType specified in project-schema.xml).
+</p>
+<p>
+    If you have a turbine-schema.xml file in your WEB-INF/conf
+    directory, the project-om ant task will generate all of the
+    Turbine*, BaseTurbine*, and map.Turbine* objects for you.
+    These will not be used by Turbine. They will only confuse
+    you. The best thing to do for this is to rename your
+    turbine-schema.xml file to something like turbine-schema.nogenerate.
+</p>
+</section>
+
+<section name="XML-RPC service">
+<p>
+    My TurbineResources.properties did not have settings to
+    configure the secure options. This caused initialization
+    of the service to fail. To fix this, I simply obtained all
+    of the configuration settings from the TurbineResources.properties
+    included with the source version.
+</p>
+<p>
+    The service does not listen on the loopback interface by default
+    any longer. There were no other changes that are required to get
+    this service up and running under T2.2.
+</p>
+</section>
+
+<section name="Other services">
+<p>
+    Intake, Security, and Scheduler all work without a problem
+    after migrating to T2.2.
+</p>
+</section>
+
+<section name="Maven">
+<p>
+    You may like to consider using
+    <a href="http://maven.apache.org/maven-1.x/">Maven</a> to
+    build your project.  The document
+    <a href="http://wiki.apache.org/turbine/TDK/Maven">
+    Starting your project and database with TDK2.2 and Maven</a>
+    provides some information that can be adapted for this purpose
+    (jump down to the "Moving The Sample" heading for the
+    documentation relevant to an existing project).
+</p>
+</section>
+
+<section name="Updates to this document">
+<p>
+    This document is by no means complete or totally accurate. We welcome
+    suggestions as to how it might be improved, particularly if you have
+    just completed migrating an application by following this howto.
+</p>
+</section>
+
+</body>
+</document>
diff --git a/src/site/xdoc/howto/migrate-from-2_2-howto.xml b/src/site/xdoc/howto/migrate-from-2_2-howto.xml
new file mode 100644
index 00000000..768be2e6
--- /dev/null
+++ b/src/site/xdoc/howto/migrate-from-2_2-howto.xml
@@ -0,0 +1,294 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<document>
+
+ <properties>
+  <title>Migrating from 2.2 to 2.3</title>
+ </properties>
+
+<body>
+
+<section name="Introduction">
+<p>
+    This document describes the basic steps needed to migrate an
+    application written for Turbine 2.2 to Turbine 2.3.
+</p>
+<p>
+    You may find that migrating to 2.3 is not all that difficult -
+    it should certainly be less trouble than migrating from 2.1 to
+    2.2. Most of the pain in figuring out this migration process
+    has been documented in the mailing list archives, but is
+    summarized here for your convenience.
+</p>
+</section>
+
+<section name="Deprecated And Removed Services">
+<p>
+    In 2.3, many services have been deprecated or removed wholly.
+    Below are the changes I made to get my 2.2 app to work under 2.3.
+</p>
+<p>
+    Remove from tr.props ( and any properties that start with services.XXX):
+</p>
+<source>
+<![CDATA[
+ services.PoolBrokerService.classname=org.apache.turbine.services.db.TurbinePoolBrokerService
+ services.MapBrokerService.classname=org.apache.turbine.services.db.TurbineMapBrokerService
+ services.ResourceService.classname=org.apache.turbine.services.resources.TurbineResourceService
+ services.LoggingService.classname=org.apache.turbine.services.logging.TurbineLoggingService
+]]>
+</source>
+<p>
+    Note: Removing LoggingService removes all logging stuff from
+    TurbineResources.properties as well! Now you use a Log4j.properties:
+    WEB-INF\conf\Log4j.properties. You need at least an empty file,
+    otherwise log4j complains, but something like this will be better:
+</p>
+<source>
+<![CDATA[
+# -------------------------------------------------------------------
+# Log4j.properties
+# -------------------------------------------------------------------
+
+# This first category is required and the category
+# must be named 'default'. This is used for all logging
+# where an explicit category is not specified.
+
+log4j.category.default = INFO, default
+log4j.category.org.apache.turbine.services.pull.util.UIManager = DEBUG, default
+
+log4j.appender.default = org.apache.log4j.RollingFileAppender
+log4j.appender.default.file = logs/turbine.log
+log4j.appender.default.MaxFileSize = 1024KB
+log4j.appender.default.MaxBackupIndex = 5
+log4j.appender.default.append = true
+log4j.appender.default.layout = org.apache.log4j.PatternLayout
+log4j.appender.default.layout.conversionPattern = %d %-5p [%-10t] %c{2} - %m%n
+
+log4j.appender.email = org.apache.log4j.net.SMTPAppender
+log4j.appender.email.BufferSize = 512
+log4j.appender.email.From = @your-from-address@
+log4j.appender.email.SMTPHost = @your-mail-host@
+log4j.appender.email.Subject = Turbine Error Report
+log4j.appender.email.To = @your-to-address@
+log4j.appender.email.layout = org.apache.log4j.PatternLayout
+log4j.appender.email.layout.conversionPattern = %d %-5p [%-10t] %c{2} - %m%n
+
+# This category is used in the BasePeer class. All
+# SQL generated will be logged if the category
+# priority is set to DEBUG
+
+log4j.category.org.apache.torque.util.BasePeer = DEBUG, org.apache.torque.util.BasePeer
+log4j.additivity.org.apache.torque.util.BasePeer = false
+log4j.appender.org.apache.torque.util.BasePeer = org.apache.log4j.RollingFileAppender
+log4j.appender.org.apache.torque.util.BasePeer.file = logs/sql.log
+log4j.appender.org.apache.torque.util.BasePeer.MaxFileSize = 1024KB
+log4j.appender.org.apache.torque.util.BasePeer.MaxBackupIndex = 3
+log4j.appender.org.apache.torque.util.BasePeer.append = true
+log4j.appender.org.apache.torque.util.BasePeer.layout = org.apache.log4j.PatternLayout
+log4j.appender.org.apache.torque.util.BasePeer.layout.conversionPattern = %d %-5p [%-10t] %c{1} - %m%n
+
+log4j.category.@your-package@.modules.scheduledjobs = DEBUG, scheduledjobs, email
+log4j.additivity.@your-package@.modules.scheduledjobs = false
+log4j.appender.scheduledjobs = org.apache.log4j.RollingFileAppender
+log4j.appender.scheduledjobs.file = logs/batch.log
+log4j.appender.scheduledjobs.MaxFileSize = 256KB
+log4j.appender.scheduledjobs.MaxBackupIndex = 5
+log4j.appender.scheduledjobs.append = true
+log4j.appender.scheduledjobs.layout = org.apache.log4j.PatternLayout
+log4j.appender.scheduledjobs.layout.conversionPattern = %d %-5p [%-10t] %c{1} - %m%n
+]]>
+</source>
+
+</section>
+
+<section name="Commons-logging Replaces Built-in Logging">
+<p>
+    In 2.3, the built in logging has been deprecated in favor of using
+    commons-logging. Therefore, where ever you have this import:
+</p>
+<source>
+<![CDATA[
+import org.apache.turbine.util.Log;
+]]>
+</source>
+<p>
+	you will need to remove it and replace it with:
+</p>
+<source>
+<![CDATA[
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+]]>
+</source>
+<p>
+	Also, instead of calling static methods of the old Log object:
+	Log.debug("my message") you will need instead to do this:
+</p>
+	<source>
+<![CDATA[
+ private static Log log = LogFactory.getLog(Audit.class);
+ .
+ .
+ .
+ log.debug("My message");
+]]>
+</source>
+<p>
+	The advantage of this is that now in your logging messages, you will know
+	what class the message is coming from, versus the old way where all you
+	got was the message and you would have to embed the name of the action to
+	know what was emitting the logging message! Also, this makes your
+	underlying logging architecture pluggable. If you use jdk1.4, you can
+	plug in the java logging, or use log4j.  See the example Log4j.properties
+	file above to see a few of the possibilities.
+</p>
+</section>
+
+<section name="Use VelocityOnly Layout">
+<p>
+    Change from VelocityECSLayout to VelocityOnly Layout - see:
+	<a href="velocityonlylayout-howto.html">VelocityOnlyLayout Howto</a>.
+</p>
+</section>
+
+<section name="New Dependencies">
+<p>
+    In order to make the Turbine jar smaller, some things have been moved to
+    commons. There are in fact a raft of new dependencies that you should
+    ensure you use as part of your application - see:
+    <a href="../dependencies.html">Dependencies</a>.
+</p>
+</section>
+
+<section name="earlyInit Parameter For Selected Services">
+<p>
+    In order to get some services to work under 2.3, it is necessary to set
+    an earlyInit parameter in TurbineResources.propertiess:
+</p>
+<source>
+<![CDATA[
+services.PullService.earlyInit=true
+services.SessionService.earlyInit=true
+]]>
+</source>
+<p>
+	If your service is not being initialized as you would expect then try
+	setting this flag for it.
+</p>
+</section>
+
+<section name="New Optional URI Handling Tools">
+<p>
+	Under 2.3 there are new URI handling tools with a significant refactoring
+	of how relative and absolute URL's are handled in Turbine. Briefly, the
+	new tools avoid the confusion that arose previoulsy from mixing tools
+	with internal classes, providing uniform access to the various URI types
+	in Turbine. <strong>These new tools are backwards-compatible with your old
+	$link and $content tools, so you should not have to change any of your
+	templates if you decide to use the new tools.</strong>
+</p>
+<p>
+	To use the new tools, simply redefine the following pull tools in your
+	TurbineResources.properties:
+</p>
+	<source>
+<![CDATA[
+tool.request.link    = org.apache.turbine.services.pull.tools.TemplateLink
+tool.request.content = org.apache.turbine.services.pull.tools.ContentTool
+]]>
+</source>
+<p>
+	If you used some of the other tools for creating URL's, then there are
+	analogous new ones as well:
+</p>
+	<source>
+<![CDATA[
+org.apache.turbine.services.pull.tools.RelativeTemplateLink
+org.apache.turbine.services.pull.tools.TemplateLinkWithSlash
+]]>
+</source>
+</section>
+
+<section name="Ensure you refer to your templates correctly">
+<p>
+    Places where you might previously have got away with using forward slashes
+    ("/") in your references to template names will need to be corrected (note
+    that this does not apply to the Velocity #parse() and #include()
+    statements which operate at a lower level). See:
+    <a href="../services/template-service.html">Template Service</a>.
+</p>
+</section>
+
+<section name="Update to the latest DTDs for Intake and Torque">
+<p>
+    Updating your Intake configuration xml file and your Torque schema files
+    to use the most recent DTDs will ensure that the DTDResolver can be used
+    when validating these files.  Deprecation warnings may be produced while
+    these files are being processed - as with your application code you should
+    aim to update these files so that no deprecation warnings are produced
+    before the next Turbine release.
+</p>
+</section>
+
+<section name="Extending Turbine User">
+<p>
+    Refer to <a href="../services/torque-security-service.html">Torque
+    Security Service</a> for information on extending TurbineUser in Turbine
+    2.3 - this is now much easier than it was in previous releases.  You
+    may also want to refer to
+    <a href="http://mail-archives.apache.org/eyebrowse/ReadMsg?listName=turbine-dev@jakarta.apache.org&amp;msgNo=15077">
+    this message from the mail archive</a> - the quoted text from Henning is
+    great and Wei points to a couple of additional messages that may also
+    prove useful.
+</p>
+<p>
+    In the past you may have used a customised MapBuilder
+    (database.maps.builder in TurbineResources.properties) as part of
+    extending your user object - this is no longer required if you use the
+    Torque Security Service.  In addidion to this you need to ensure that
+    you replace any references you may have made to the old security related
+    peer classes in any Criteria with the new classes that Torque generates
+    for you as referring to the old ones will result in an inconsistent
+    database map such that your extended user attributes may not consistently
+    be maintained.
+</p>
+</section>
+
+<section name="Building Torque OM Classes">
+<p>
+	You will need to use Maven b9 or above in order to build the Torque
+	Security Service and even then you should install the latest available
+	release of the <a href="http://db.apache.org/torque/maven-howto.html">
+	Torque generator</a> plugin.
+</p>
+</section>
+
+<section name="Updates to this document">
+<p>
+    This document is by no means complete or totally accurate. We welcome
+    suggestions as to how it might be improved, particularly if you have
+    just completed migrating an application by following this howto.
+</p>
+</section>
+
+</body>
+</document>
diff --git a/src/site/xdoc/howto/migrate-from-2_3-howto.xml b/src/site/xdoc/howto/migrate-from-2_3-howto.xml
new file mode 100644
index 00000000..5824326c
--- /dev/null
+++ b/src/site/xdoc/howto/migrate-from-2_3-howto.xml
@@ -0,0 +1,117 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<document>
+
+ <properties>
+  <title>Migrating from 2.3 to 4.0</title>
+ </properties>
+
+<body>
+
+<section name="Introduction">
+<p>
+    This document describes the basic steps needed to migrate an
+    application written for Turbine 2.3 to Turbine 4.0.
+</p>
+<p>
+	Migrating from Turbine 2.3 to Turbine 4.0 is mostly a task of
+	moving from the old service format to the new one. One of the
+	biggest purposes with Turbine 4 was to decouple the different services
+	and move them to <a href="http://turbine.apache.org/fulcrum/">Fulcrum</a>.
+	Many of the released components of Fulcrum correspond to
+	a previous Turbine service that is no longer bundled with the
+	Turbine core.
+</p>
+<p>
+	The services has been converted to Avalon components and do not
+	implement the Service interface any more. Turbine still handles
+	services that do implement the Service interface though so no
+	rewrite is necessary if you have written services of your own.
+	The new services can also be accessed in pretty much the same way
+	as the old ones, as long as the AvalonComponentService is properly configured.
+</p>
+</section>
+
+<section name="Accessing the new services">
+<p>
+	What needs to be done to access the decoupled services can be
+	summarised in 4 steps:
+	<ul>
+		<li>Make sure the AvalonComponentService is properly configured</li>
+		<li>Add the services you need to your project dependency and to roleConfiguration.xml</li>
+		<li>Access the Fulcrum services with class name instead of service name</li>
+		<li>Remove any reference to the static facade classes and access the interfaces directly</li>
+	</ul>
+</p>
+<subsection name="Make sure the AvalonComponentService is properly configured">
+<p>
+	The AvalonComponentService allows you to retrieve the new services
+	via the old TurbineServices interface. Make sure that the AvalonComponentService
+	is added in your TurbineResources.properties and that you use TurbineYaafiComponentService as
+	the implementing class.
+</p>
+<source>
+<![CDATA[
+services.AvalonComponentService.classname=org.apache.turbine.services.avaloncomponent.TurbineYaafiComponentService
+services.AvalonComponentService.earlyInit=true
+]]>
+</source>
+<p>
+	The service <em>must</em> be the first service in TurbineResources.properties and it <em>must</em> be initialized early.
+	Also make sure that <a href="http://turbine.apache.org/fulcrum/fulcrum-yaafi/">Fulcrum YAAFI</a>
+	is added to your project dependency.
+</p>
+</subsection>
+<subsection name="Add the services you need to your project dependency and to roleConfiguration.xml">
+<p>
+	Many services that were previously included in Turbine has been converted to Avalon
+	components and moved to Fulcrum. You only need to add the ones used in your project as
+	a dependency. Each service has its own documentation and it is described on their project
+	page how you can configure them, but common for all is that they need to be added to your
+	roleConfiguration.xml file. Adding a service to roleConfiguration.xml is equivalent to adding
+	a Turbine service to TurbineResources.properties.
+</p>
+</subsection>
+<subsection name="Access the Fulcrum services with class name instead of service name">
+<p>
+	As you may have noticed in the documentation for the Fulcrum components, the name for
+	the different services is the full class name. Therefore the input parameter in the
+	getService method of TurbineServices needs to be the full class name of the service.
+	Usually this is stored in a static field called ROLE. Ex:
+</p>
+<source>
+<![CDATA[
+ParseService parserService = (ParserService)TurbineServices.getInstance().getService(ParserService.ROLE);
+]]>
+</source>
+</subsection>
+<subsection name="Remove any reference to the static facade classes and access the interfaces directly">
+<p>
+	The new services do not have a static facade class like the old ones
+	(org.apache.turbine.services.localization.Localization for LocalizationService,
+	org.apache.turbine.services.cache.TurbineGlobalCache for GlobalCacheService etc).
+	If you have used these facade classes, you now need to access the service directly via
+	the interface instead. How to access the classes is described in the previous section.
+</p>
+</subsection>
+</section>
+</body>
+</document>
diff --git a/src/site/xdoc/howto/migrate-from-4_0-howto.xml b/src/site/xdoc/howto/migrate-from-4_0-howto.xml
new file mode 100644
index 00000000..37383a92
--- /dev/null
+++ b/src/site/xdoc/howto/migrate-from-4_0-howto.xml
@@ -0,0 +1,489 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<document>
+
+ <properties>
+  <title>Migrating from 4.0 to 5.0</title>
+ </properties>
+
+<body>
+
+<section name="Introduction">
+<p>
+    This document describes the basic steps needed to migrate an
+    application written for Turbine 4.0 to Turbine 5.0.
+</p>
+<p>
+	Migrating from Turbine 4.0 to Turbine 5.0 is mostly a task of
+	updating any references to commons-config and insuring that you
+    are using Parts for file upload rather than the old FileItem object.
+</p>
+</section>
+
+
+<section name="Updating configuration">
+
+	<subsection name="Log4j changes">
+		<p>
+		    TurbineResources.properties have changed making it less verbose
+		    to point to the log4j config file.
+        
+        Secondly, we have upgraded to Log4j2. We still keep the file as is (i.e. outside classpath), as this is what Turbine did all the way. 
+		
+			Old config line:
+<source>
+<![CDATA[
+
+        # -------------------------------------------------------------------
+        #
+        #  L O G 4 J - L O G G I N G
+        #
+        # -------------------------------------------------------------------
+        
+        log4j.file = WEB-INF/conf/log4j.properties
+    
+]]>
+			</source>
+		
+			New config line:
+<source>
+<![CDATA[
+        # -------------------------------------------------------------------
+        #
+        #  L O G 4 J 2 - L O G G I N G
+        #
+        # -------------------------------------------------------------------
+        
+        log4j.file = log4j2.xml
+]]>
+</source>
+
+        </p>
+
+	</subsection>
+
+	<subsection name="Setting character encoding">
+		<p>
+			The default character encoding typically should be set
+			by your servlet container.  For example, in Tomcat you can
+			update the server.xml in the following way to force URI connections
+			to be encoded in UTF-8.
+		</p>
+		
+<source>
+<![CDATA[
+    <!-- Define a non-SSL HTTP/1.1 Connector on port 8080 -->
+       <Connector port="8080" maxHttpHeaderSize="8192"
+                   maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
+                   enableLookups="false" redirectPort="8443" acceptCount="100"
+                   connectionTimeout="20000" disableUploadTimeout="true"
+                   URIEncoding="UTF-8"
+       />
+]]>
+</source>
+
+		<p>
+			However, earlier versions of Apache Turbine allowed you to override this
+			value by setting the input.encoding property in your TurbineResources.properties file.
+		</p>
+		
+		<p>			
+			With Turbine 5.0, you can still accomplish this same behavior, but you need
+			to make sure that you have added the encoding valve to the turbine-classic-pipeline.xml
+			to enable it.
+		</p>
+		
+		<p>			
+			In TurbineResources.properties, you can set the following parameter:
+		</p>
+
+<source>
+<![CDATA[
+        input.encoding = UTF-8
+]]>
+</source>
+
+		<p>
+			But it will not be picked up unless you edit the pipeline valves 
+			to read as follows. Note that ORDER does matter if you are not
+			seeing the behavior you expected.
+		</p>
+
+<source>
+<![CDATA[
+    <pipeline name="default">
+        <valves>
+
+            <!-- Use this valve to enable use of the input.encoding
+                    parameter defined in your TurbineResources.properties file -->
+            <valve>org.apache.turbine.pipeline.DefaultSetEncodingValve</valve>
+
+            <valve>org.apache.turbine.pipeline.DetermineActionValve</valve>
+            <valve>org.apache.turbine.pipeline.DetermineTargetValve</valve>
+            <valve>org.apache.turbine.pipeline.DefaultSessionTimeoutValve</valve>
+            <valve>org.apache.turbine.pipeline.DefaultLoginValve</valve>
+            <valve>org.apache.turbine.pipeline.DefaultSessionValidationValve</valve>
+            <valve>org.apache.turbine.pipeline.DefaultACLCreationValve</valve>
+            <valve>org.apache.turbine.pipeline.ExecutePageValve</valve>
+            <valve>org.apache.turbine.pipeline.CleanUpValve</valve>
+            <valve>org.apache.turbine.pipeline.DetermineRedirectRequestedValve</valve>
+      </valves>
+    </pipeline>
+]]>
+</source>
+
+	</subsection>
+</section>
+
+
+<section name="Migrating to Functional Interfaces and Rundata">
+	
+	<p>Functional interfaces are now used instead of abstract classes. Rundata should be removed and instead of PipelineData used, but we keep it for now. 
+     As a result <strong>AbstractValve was removed</strong> and with it the method <strong>getRunData(pipelineData)</strong> is gone.
+     You may retrieve the Rundata casted object now with <strong>pipelineData.getRunData()</strong>.
+	</p>
+	
+<source>
+<![CDATA[
+        // old
+        // RunData rundata = getRunData(pipelineData)
+        RunData rundata = pipelineData.getRunData();
+
+]]>
+	</source>
+	
+	<p>
+		Assembler derived classes in package org.apache.turbine.modules (Action, LayoutScreen, Navigation, Page, ..) 
+        are now declared as java functional interfaces instead of abstract classes. 
+        Using them in child classes might be as easy as replacing <strong>extends</strong> with <strong>implements</strong> keyword in class declaration.
+        Remark: Method signature containing checked exceptions were not changed. To use Java 8 functional lamda functions you may 
+        catch and rethrow them wrapped into a RuntimeException.
+	</p>
+	
+<source>
+<![CDATA[
+
+  // old
+  // class MyAction extends Action
+
+  class MyAction implements Action
+  
+]]>
+</source>
+
+</section>
+
+
+
+<section name="Migrating File Upload to Parts">
+	
+	<p>
+		In turbine-4.0.1 and prior, file uploads were processed through the
+		data.getParameters().getFileItem("file_field_name") method and returned
+		a FileItem object.
+	</p>
+	
+	<p>
+		With Turbine-5.0, the framework is now using Java servlet 3.1.0.
+		As such, you will need to migrate this code using the
+		new Part object from the servlet spec.  This actually saves you some
+		time since you don't have to convert the FileItem to a byte array and
+		then into an InputStream for processing.. you auto-magically get an
+		getInputStream() method on your javax.servlet.http.Part object to then
+		do as you please...
+	</p>
+<source>
+<![CDATA[
+
+        // all file items are now parts
+        Part fileItem = data.getParameters().getPart("file");
+        if (fileItem != null) {
+
+            InputStream is = fileItem.getInputStream();
+            BufferedReader bfReader = null;
+            try {
+                bfReader = new BufferedReader(new InputStreamReader(is));
+                String line = null;
+                while ((line = bfReader.readLine()) != null) {
+
+                    // do something with the input here ...
+
+                }
+            } catch (IOException e) {
+                // handle exception here	
+                e.printStackTrace();
+            } finally {
+                try {
+                    if (is != null)
+                        is.close();
+                } catch (Exception ex) {
+                    // handle exception here	
+                }
+            }
+        }
+
+]]>
+	</source>
+	
+	<p>
+		And if you really do need a byte array (for example to store the
+		contents as a binary object in the database), you can do this using the
+		following method calls.
+	</p>
+	
+<source>
+<![CDATA[
+
+  InputStream is = fileItem.getInputStream();
+  byte[] byteArray = IOUtils.toByteArray(is);
+  
+]]>
+</source>
+
+</section>
+
+
+<section name="Migrating to Quartz for Job Scheduling">
+
+<p>
+    Quartz was introduced as a replacement for job scheduling starting
+    with Turbine 4.0. It provides Unix cron like abilities to manage 
+    the automatic execution of tasks (or jobs) within your Turbine application.
+</p>
+
+<p>
+    An example of a job might be periodic data or log cleanup that you
+    want to automate within the application itself.
+</p>
+
+	<subsection name="Creating a job">
+
+    <p>
+        Job creation has not really changed from the way jobs
+        were created in older versions of Turbine. You can refer
+        to the older documentation on how to create a job. For ease of
+        following the notes below however, we will add one simple job.
+    </p>
+
+    <p>
+        Create the job class in com.myapp.modules.scheduledjobs.MyTurbineJob.java
+    </p>
+
+
+<source>
+<![CDATA[
+
+package com.myapp.modules.scheduledjobs;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.turbine.modules.ScheduledJob;
+import org.apache.turbine.services.schedule.JobEntry;
+import org.apache.turbine.services.security.SecurityService;
+
+public class MyTurbineJob extends ScheduledJob {
+
+	/** Logging */
+	private static Log log = LogFactory.getLog(MyTurbineJob.class);
+
+    // Track the number of times the job has been run
+	private static int taskcount = 0;
+
+	/**
+	 * Constructor
+	 */
+	public MyTurbineJob() {
+	}
+
+	@Override
+	public void run(JobEntry job) throws Exception {
+
+		try {
+
+            log.info("Job run: " + taskcount);
+            // do some interesting work to be scheduled here...
+
+		} catch (Exception e) {
+			log.error("An error occurred running MyTurbineJob: " + e.toString());
+		}
+
+		taskcount++;
+	}
+}
+]]>
+</source>
+
+    </subsection>
+
+	<subsection name="Quartz service configuration">
+
+    <p> The Quartz scheduler is implemented as a Fulcrum component and needs
+        to be defined in the roleConfiguration.xml and componentConfiguration.xml
+        files in the WEB-INF/conf directory.
+    </p>
+
+    <p> Modify the 
+        <b>WEB-INF/conf/roleConfiguration.xml</b>
+    </p>
+
+<source>
+<![CDATA[
+
+
+<role-list>
+
+    ...
+
+    <!-- Service required for the QuartzSchedulerService -->
+    <role
+        name="org.apache.fulcrum.quartz.QuartzScheduler"
+        shorthand="quartz"
+        default-class="org.apache.fulcrum.quartz.impl.QuartzSchedulerImpl" />
+        
+</role-list>
+]]>
+</source>
+
+    <p> Modify the 
+        <b>WEB-INF/conf/componentConfiguration.xml</b>
+    </p>
+
+<source>
+<![CDATA[
+
+<componentConfig>
+    ...
+
+     <quartz>
+        <configuration>
+            <properties>
+                <parameter name="org.quartz.scheduler.instanceName" value="TestScheduler"/>
+                <parameter name="org.quartz.scheduler.instanceId " value="AUTO"/>
+                <parameter name="org.quartz.scheduler.skipUpdateCheck" value="true"/>
+                <parameter name="org.quartz.threadPool.class" value="org.quartz.simpl.SimpleThreadPool"/>
+                <parameter name="org.quartz.threadPool.threadCount" value="3"/>
+                <parameter name="org.quartz.threadPool.threadPriority" value="5"/>
+                <parameter name="org.quartz.jobStore.misfireThreshold" value="60000"/>
+                <parameter name="org.quartz.jobStore.class" value="org.quartz.simpl.RAMJobStore"/>
+                <parameter name="org.quartz.plugin.jobInitializer.class" value="org.quartz.plugins.xml.XMLSchedulingDataProcessorPlugin"/>
+                <parameter name="org.quartz.plugin.jobInitializer.fileNames" value="../conf/quartz.xml"/>
+                <parameter name="org.quartz.plugin.jobInitializer.failOnFileNotFound" value="true"/>
+                <parameter name="org.quartz.plugin.jobInitializer.scanInterval" value="120"/>
+                <parameter name="org.quartz.plugin.jobInitializer.wrapInUserTransaction" value="false"/>
+            </properties>
+        </configuration>
+    </quartz>  
+
+</componentConfig>
+
+]]>
+</source>
+
+<p> 
+    Next, enable the Quartz scheduler service in the TurbineResources.properties file. 
+</p>
+
+
+<source>
+<![CDATA[
+services.SchedulerService.classname=org.apache.turbine.services.schedule.QuartzSchedulerService
+]]>
+</source>
+
+<p> 
+Finally, we need the configuration file for Quartz itself to run the job. You can do this by creating a quartz.xml file in your WEB-INF/conf directory.
+</p>
+
+<p>
+
+   If you want to change the name, check the component configuration above
+   which defines the org.quartz.plugin.jobInitializer.fileNames value.
+</p>
+
+<p>
+    This example quartz configuration is set to run our test job every 15 minutes.
+</p>
+
+<source>
+<![CDATA[
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor 
+	license agreements. See the NOTICE file distributed with this work for additional 
+	information regarding copyright ownership. The ASF licenses this file to 
+	you under the Apache License, Version 2.0 (the "License"); you may not use 
+	this file except in compliance with the License. You may obtain a copy of 
+	the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required 
+	by applicable law or agreed to in writing, software distributed under the 
+	License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS 
+	OF ANY KIND, either express or implied. See the License for the specific 
+	language governing permissions and limitations under the License. -->
+<job-scheduling-data
+	xmlns="http://www.quartz-scheduler.org/xml/JobSchedulingData"
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://www.quartz-scheduler.org/xml/JobSchedulingData http://www.quartz-scheduler.org/xml/job_scheduling_data_2_0.xsd"
+	version="2.0">
+	<pre-processing-commands>
+		<delete-jobs-in-group>*</delete-jobs-in-group>
+		<!-- clear all jobs in scheduler -->
+		<delete-triggers-in-group>*</delete-triggers-in-group>
+		<!-- clear all triggers in scheduler -->
+	</pre-processing-commands>
+	<processing-directives>
+		<!-- if there are any jobs/trigger in scheduler of same name (as in this 
+			file), overwrite them -->
+		<overwrite-existing-data>true</overwrite-existing-data>
+		<!-- if there are any jobs/trigger in scheduler of same name (as in this 
+			file), and over-write is false, ignore them rather then generating an error -->
+		<ignore-duplicates>false</ignore-duplicates>
+	</processing-directives>
+	<schedule>
+		<job>
+			<name>MyTurbineJob</name>
+			<group>TURBINE</group>
+			<description>Perform some task at a specified time</description>
+			<job-class>org.apache.turbine.services.schedule.JobEntryQuartz</job-class>
+		</job>
+		<trigger>
+			<simple>
+				<name>MyTurbineJobTrigger</name>
+				<group>TURBINE</group>
+				<job-name>MyTurbineJob</job-name>
+				<job-group>TURBINE</job-group>
+				<start-time>2018-06-01T00:00:00</start-time>
+				<misfire-instruction>MISFIRE_INSTRUCTION_RESCHEDULE_NOW_WITH_EXISTING_REPEAT_COUNT</misfire-instruction>
+				<repeat-count>-1</repeat-count>
+        		<!--  check every 15 minutes -->
+				<repeat-interval>900000</repeat-interval>
+			</simple>
+		</trigger>
+	</schedule>
+</job-scheduling-data>
+
+
+	]]>
+</source>
+
+</subsection>
+
+</section>
+
+</body>
+</document>
diff --git a/src/site/xdoc/howto/pullmodel-howto.xml b/src/site/xdoc/howto/pullmodel-howto.xml
new file mode 100644
index 00000000..cdc5d6d3
--- /dev/null
+++ b/src/site/xdoc/howto/pullmodel-howto.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<document>
+
+ <properties>
+  <title>Pull Model Howto</title>
+ </properties>
+
+<body>
+
+<section name="Using the pull model with Turbine 2">
+
+<p>
+Turbine 2 can be used with two different programming models - the push model
+and the pull model.  The difference is in how the Context is built up.  The
+Context is used by the Velocity or WebMacro template files to "fill in the
+blanks" and introduce dynamic data into a static HTML-based template.  This
+programming concept is incredibly powerful - because it allows the web
+designer, who may be experienced with HTML, CSS, and Javascript but not
+Java, to put data fields wherever they want on a page without having to ask
+the Java programmers to change a Java class and recompile.  For more
+information on which to choose for your Turbine application, read Jon
+Stevens' informative commentary <a href="../pullmodel.html">Push vs
+Pull</a>.
+</p>
+
+<p>
+Also see the <a href="../services/pull-service.html">Pull Service</a>
+Documentation
+for another explanation of how the Pull Service works with Tools.
+</p>
+
+<p>
+The push model is based on a one-to-one mapping of Java Screen
+classes and Velocity template files.  The Screen class puts key/value pairs
+into the Context.  The <a href="context-howto.html">Context Howto</a>
+explains this approach.
+</p>
+
+<p>
+The pull model allows the web designer even more freedom than the push
+model. Java programmers can create globally accessible Java classes known as
+Tools.   These Tools are going to be useful for getting data out of a
+service and bringing it to the presentation layer, authenticating users, or
+creating links (see the TemplateLink tool that is built into Turbine).
+</p>
+</section>
+
+<section name="Pull Tool Implementation">
+<p>
+Your SimpleSecurityTool should implement ApplicationTool, which is a simple
+interface with two methods, init(Object data) and refresh.  It could be a
+facade class that calls other classes, or it could have its own business
+logic.
+</p>
+</section>
+
+<section name="Entries in TurbineResources.properties">
+<p>
+To make the Tool available to Turbine, you need to define your Tools in the
+TurbineResources.properties file.  The "Pull Service" section of the
+properties file is where the tools are listed.  You can use the following
+syntax (all explained in the TurbineResources.properties):
+</p>
+
+
+<source><![CDATA[
+tool.<Scope>.<Id> = <Classname>
+
+tool.request.formsTool = com.yourcompany.turbine.tools.SimpleFormsTool
+]]></source>
+
+<p>
+Classname is your java classname -
+com.yourcompany.turbine.tools.SimpleFormsTool
+</p>
+
+<p>
+Id is a unique identifier that you will use in your Velocity templates -
+formsTool, for instance.
+</p>
+
+<p>
+Scope defines the life cycle of the Tool.  There are four, global, request,
+session, and persistent.
+</p>
+
+<p>
+Global: The tool is instantiated once and is available to all templates for
+all requests. Must be threadsafe.
+</p>
+
+<p>
+Request: The tool is instantiated once for every request to Turbine.
+Doesn't need to be threadsafe.  The link, page, and flux tools are all
+defined as request scope.
+</p>
+
+<p>
+Session: The tool is instantiated once for each user session. Should be
+threadsafe.  Useful for tools that might hold user profiles, or items in a
+shopping cart.
+</p>
+
+<p>
+Persistent: Tool is instantiated once for each user session, and is stored
+along with the user information.  Must be threadsafe and implement
+Serializable.  An example of how this scope would be used would be great!
+</p>
+
+<p>
+Additional tool-defined properties can be configured in the
+TurbineResources.properties. The syntax is defined under the "Pull Service"
+section.
+</p>
+
+</section>
+
+</body>
+</document>
diff --git a/src/site/xdoc/howto/python-howto.xml b/src/site/xdoc/howto/python-howto.xml
new file mode 100644
index 00000000..533caca0
--- /dev/null
+++ b/src/site/xdoc/howto/python-howto.xml
@@ -0,0 +1,182 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<document>
+
+ <properties>
+  <title>Python Howto</title>
+ </properties>
+
+ <body>
+  <section name="Turbine Python Support">
+  <p>
+    Turbine has support for creating assemblers (see the <a href="fsd.html">
+    specifications</a>) with Python, by making use of
+    <a href="http://www.jpython.org">JPython technology</a>.
+  </p>
+  <p>
+    The first question that comes to mind is why one would want do to something
+    like this.  Here are some of the reasons you might want to do this:
+  </p>
+    <ul>
+        <li>
+            Python is an interpreted language which means that you do not have
+            to recompile and copy a new jar each time you make changes.
+        </li>
+
+        <li>
+            Although Python is interpreted it is compiled to java bytecode.
+            Performance is on par with native java code.
+        </li>
+
+        <li>
+            Python is very easy to learn.  This, together with the fact that
+            you don't need to use a compiler, makes it possible for people with
+            little java experience to create screens.
+        </li>
+
+        <li>
+            You can rapidly build a prototype using python, and later on find
+            that it is not necessary to systematically move to java :-)
+        </li>
+    </ul>
+  </section>
+
+  <section name="Setting Up Python for Turbine">
+    <p>
+        The first thing is to download JPython from www.jpython.org and copy
+        the jpython.jar file into your turibe/lib directory.  Now you need to
+        prepare and compile the jpython files like this:
+<source>
+build prepare-python
+build jar
+</source>
+        This will create a new turbine library that contains the Python code.
+        You need to copy this new .jar file to your application's lib
+        directory.
+    </p>
+    <p>
+        Now we need to edit the TurbineResources.properties.  Add the following
+        keys to your application's properties:
+    </p>
+<source><![CDATA[
+services.AssemblerBrokerService.assembler.screen=
+org.apache.turbine.util.assemblerbroker.python.PythonScreenFactory
+services.AssemblerBrokerService.assembler.action=
+org.apache.turbine.util.assemblerbroker.python.PythonActionFactory
+
+services.AssemblerBrokerService.python.path=/path/to/python
+]]></source>
+    <p>
+        The first two registers the Python Assembler Factories with the
+        AssemblerBrokerService.  The last line tells the Python interpreter
+        where to find all the .py files for your application.
+    </p>
+    <p>
+        In the root of your services.AssemblerBrokerService.python.path
+        you need to add a file named config.py that looks like this:
+    </p>
+
+<source><![CDATA[
+import java
+
+from java.io import *
+from java.util import *
+
+sys.add_package("org.apache.turbine.modules.screens")
+sys.add_package("org.apache.turbine.modules")
+sys.add_package("org.apache.turbine.util.db")
+sys.add_package("org.apache.turbine.util")
+sys.add_package("org.apache.turbine.services.security.TurbineSecurity")
+sys.add_package("org.webmacro.servlet")
+
+
+from org.apache.turbine.modules.screens  import WebMacroSiteScreen
+from org.apache.turbine.modules          import Action
+from org.apache.turbine.util.db          import Criteria
+from org.apache.turbine.util             import RunData
+from org.webmacro.servlet                import WebContext
+from org.apache.turbine.services.security   import TurbineSecurity
+]]></source>
+
+      <p>
+        JPython sometimes gets a bit confused with the Servlet Engine
+        classloader, which forces us to call sys.add_package for each java
+        package that we wish to use in our Python code.  You also need to
+        import all the classes that you wish to use explicitly.  You needn't
+        add the classes here, but it avoid some duplicate declarations at the
+        top of each screen/action.
+    </p>
+    </section>
+
+    <section name="Using Python with Turbine">
+    <p>
+        To create python screens we use exactly the same methodology than for
+        normal java screens.  First you need a /screens subdirectory in your
+        services.AssemblerBrokerService.python.path.  This is where your
+        screen code will live.  Layouts goes in /layouts, actions in /actions
+        and so forth (just remember to register the appropriate assembler
+        factories).
+    </p>
+    <p>
+        I'm going to create a sample WebMacro screen.  First we need a .py file
+        where this screen can live.  The .py file should have the same name as
+        your .wm file and it must be all lower case.  Inside this file we
+        create a new class with the same name as the file, but in this the
+        first letter is uppercase (the rest is always lower case).  To override
+        a method is fairly simple (just create a new method with the same
+        name).
+    </p>
+    <p>
+        There is one problem however - Python does not support method
+        overloading based on type signatures, so usually the simplest for is
+        used, which is doBuildTemplate( RunData data ) for WebMacroSiteScreen
+        in stead of doBuildTemplate( RunData data, WebContext context ).  You
+        have two options to overcome this problem. (1) Create a new superclass
+        that exposes a method under a different name or (2) just call
+        getContext in your python code.  I usually just go for the second
+        option because it is fairly straight forward anyway.
+    </p>
+    <p>
+        Now for the code.  Let's create a screen called Test.  First create a
+        test.wm file (I assumer everybody knows how to do this).  Now create a
+        test.py and place it in the python-path/screens directory.  It should
+        look something like this:
+    </p>
+
+<source><![CDATA[
+class Subjectslist(WebMacroSiteScreen):
+   def doBuildTemplate (self,data):
+        context = self.getContext(data)
+        context.put ("me","Leon")
+        context.put ("text","Python is cool");
+]]></source>
+
+    <p>
+        For more information about the self parameter see the Python docs.  You
+        can call any java code that you would normally be able to use (just
+        remember to add it to conf.py) including database, services, etc. You
+        can also freely use any of the Python built-in types and any Python
+        module that was built on 100% pure Python.
+    </p>
+  </section>
+
+ </body>
+</document>
diff --git a/src/site/xdoc/howto/security-howto.xml b/src/site/xdoc/howto/security-howto.xml
new file mode 100644
index 00000000..a712fb5a
--- /dev/null
+++ b/src/site/xdoc/howto/security-howto.xml
@@ -0,0 +1,249 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<document>
+
+ <properties>
+  <title>Security Howto</title>
+ </properties>
+
+<body>
+
+<section name="Turbine Security">
+
+<p>
+The Turbine Security includes a <a href="../services/security-service.html">Security Service</a>
+as well as Actions and Screens that can be extended in the Templating Services.
+</p>
+
+</section>
+
+
+<!-- Start -->
+
+
+<section name="Users, Groups, Roles and Permissions">
+
+<p>
+The default Relational Database schema that Turbine uses for the database security
+service includes the
+data structure for the managing of permissions.
+The default or core schema can be viewed at;
+</p>
+
+<p>
+<ul><a href="../turbine-schema.html">Turbine Core Schema</a></ul>
+</p>
+
+<p>
+The main tables are TURBINE_GROUP, TURBINE_USER, TURBINE_ROLE and TURBINE_PERMISSION.
+The Permissions are the individual actions a user is allowed to take in the system.
+The Role is a container for the Permissions, in other words a Role can be made of
+many Permissions. User is an account that is interaction with the System and the Group
+is a something that a User would want to do something in. In the Turbine mailing lists
+it has often been described in the same way as a project. In a project you have fulfill
+a role, however a User doesnt "belong" to a project they merely have a role in that
+project ( or group ). In this manner too a User can have many Roles within the one
+Group. For instance a User may have the Role Developer in the Group, but may also have
+the Role of Administrator as well. While initially confusing at first, as there
+are no group-user or role-user containers, it is a flexible system and strong system.
+</p>
+
+</section>
+
+
+<section name="Access Control Lists">
+
+<p>
+A User's interaction through the system is controlled by the Permissions they are
+able to partake in. The AccessControlLists manage this information and present it via
+RunData and User Interfaces to the application. The RunData interface through the
+getACL() method presents the AccessControlList Object.
+</p>
+
+<source>
+//get the AccessControlList Object
+//from RunData
+AccessControlList acl = data.getACL();
+
+//check if the User ( from the http request )
+//has permission to view the invoices
+if( acl.hasPermission("viewinvoice") )
+{
+    data.setMessage("You have permission to view the invoices.");
+    setTemplate(data, "Invoice.vm");
+}
+else
+{
+    data.setMessage("You do not have Permission to view the Invoices");
+    setTemplate(data, "UnauthorizedRequest.vm");
+}
+</source>
+
+<p>
+This will check if the User has permission to view this in the Global Group which
+is useful for managing Anonymous Users as well as logged in Users across your
+application. If however you need stronger security, such as only allowing users that
+have logged in, and have a Role in a specific Group, the Permission will need to be
+matched to the Group and User. As an example, assume one of your groups is "Accounting"
+and the Invoice information is only to be viewed by Usersthat have a Role in Accounting
+as well as the Permission "viewinvoice", the above method would be re-written;
+</p>
+
+<source><![CDATA[
+//get the User from RunData
+User user = data.getUser();
+
+//get the AccessControlList Object
+//from RunData
+AccessControlList acl = data.getACL();
+
+//check if the User has logged in,
+//has a role in the group and
+//has permission to view the invoices
+if( user.hasLoggedIn() &&
+    acl.hasPermission("viewinvoice", "Accounting") )
+{
+   data.setMessage("You have permission to view the invoices.");
+   setTemplate(data, "Invoice.vm");
+}
+else
+{
+   data.setMessage("You do not have Permission to view the Invoices");
+   setTemplate(data, "UnauthorizedRequest.vm");
+}
+]]></source>
+
+<p>
+If instead the Permission could be across any of the Roles the User has, the
+method acl.hasPermission(String permission, GroupSet groups), can be used. As
+always check the Javadocs for more detail.
+</p>
+
+</section>
+
+<section name="Templates and Logging In">
+
+<p>
+Managing Anonymous Users and Logged In Users poses problems in applications for managing
+the Secure/Strong parts of the application and the Unsecure/Weak parts of the
+application. In Turbine, the Action and Screen components make managing this process
+quite simple. Assume the only Velocity Template allowed to be viewed without being
+logged in is the actual Login.vm template. As this is the only Screen that
+needs to be Unsecure/Weak we can manage this via the parent of Login Screen.
+</p>
+
+
+<source>
+package com.mycompany.modules.screens;
+
+//parent which allows Users to view the screen
+public class WeakScreen extends VelocityScreen
+{
+
+    //nothing to check that the User
+    //can view this screen
+    protected void doBuildTemplate( RunData data, Context context )
+        throws Exception
+    {
+        //call to Super
+        super.doBuildTemplate(data, context);
+    }
+}
+
+package com.mycompany.modules.screens;
+
+//the java component of the Login Velocity Template
+public class Login extends WeakScreen
+{
+
+    //nothing to check that the User
+    //can view this screen
+    protected void doBuildTemplate( RunData data, Context context )
+        throws Exception
+    {
+        context.put("date",new Date());
+
+        //call to Super
+        super.doBuildTemplate(data, context);
+    }
+}
+</source>
+
+<p>
+Note that there is nothing in that method which checks that the User has logged in.
+On the other hand, for the Secure or Strong Actions and Screens we would want a
+check to ensure that the User has logged in.
+</p>
+
+<source>
+package com.mycompany.modules.screens;
+
+//Strong screen which checks for login
+public class StrongScreen extends VelocityScreen
+{
+    //check that User has Logged in before bothering
+    //to add anything to the context.
+    protected void doBuildTemplate( RunData data )
+        throws Exception
+    {
+        if (data.getUser().hasLoggedIn())
+        {
+            doBuildTemplate( data, TurbineVelocity.getContext( data ) );
+        }
+        else
+        {
+            //send the User to the Login Template
+            data.setMessage("Please Login first!");
+            setTemplate(data,"Login.vm");
+        }
+    }
+}
+
+package com.mycompany.modules.screens;
+
+//as an example use the Invoices again
+public class Invoice extends StrongScreen
+{
+    //can view this screen
+    protected void doBuildTemplate( RunData data, Context context )
+        throws Exception
+    {
+        context.put("invoice",new Invoice());
+
+        //call to Super
+        super.doBuildTemplate(data, context);
+    }
+}
+</source>
+
+<p>
+In the latter example, before the Screen populates the Context it will check for the
+User being logged in by the doBuildTemplate(data) method in the parent. If the test
+fails, the context isnt created for the Invoice screen. Another way to manage this
+is to seperate the screens into two packages, com.mycompany.modules.screens.unsecure
+and com.mycompany.modules.screens.secure and have a Default.java Screen in each
+of the packages mimicing the above approaches.
+</p>
+
+</section>
+
+</body>
+</document>
diff --git a/src/site/xdoc/howto/services-howto.xml b/src/site/xdoc/howto/services-howto.xml
new file mode 100644
index 00000000..bf563267
--- /dev/null
+++ b/src/site/xdoc/howto/services-howto.xml
@@ -0,0 +1,212 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<document>
+
+ <properties>
+  <title>Services Howto</title>
+ </properties>
+
+ <body>
+  <section name="Turbine Services Creation">
+    <p>
+      Adding your own services to Turbine is an easy task. Simply make your
+      class extend <b>org.apache.turbine.services.TurbineBaseService</b>.
+      This is necessary so that the Turbine Service Broker can start up
+      your service.
+    </p>
+
+    <p>
+      To make it known to the Turbine itself, you must configure it in
+      the TurbineResources.properties like this:
+
+<source>
+services.MyServiceName.classname = full.class.name.of.your.service
+</source>
+    </p>
+
+    <p>
+      and you're set, Turbine will now initialize the service if it is
+      requested by an application. Please be aware that your service is
+      <b>not</b> initialized right at Startup. This is called lazy init.
+      If you need your Service to start up right away, you must add another
+      property to the TurbineResources.properties:
+
+<source>
+services.MyServiceName.earlyInit = true
+</source>
+    </p>
+
+    <p>
+      If you look at the examples of the simple services like
+      servlet/TurbineServletService you'll get on speed pretty fast.
+    </p>
+</section>
+
+<section name="In a Nutshell">
+    <p>
+      <ul>
+        <li>
+          You must not try to provide a constructor with parameters, best is
+          not to provide any constructor at all, because nothing should be
+          done at construction time (You'll get the default constructor which
+          is fine for us).
+         </li>
+         <li>
+           Your Service will be instantiated exactly once. So it must be
+           threadsafe and must not use class global variables for
+           session-dependent information.
+         </li>
+         <li>
+           You should provide an init() method which is called when your
+           service is requested for the first time (or at startup if you
+           set earlyInit = true) and should initialize your service
+           dependent code. There is lots of confusion of how this init()
+           method should look like because Turbine used different methods
+           of Service initialization. Beginning with Turbine 2.2, you should
+           only use the parameterless variant:
+         </li>
+      </ul>
+    </p>
+<source>
+public void init() throws InitializationException
+{
+}
+</source>
+    <p>
+      <ul>
+        <li>
+          You <b>must</b> call setInit(true) if your service initializes
+          correctly. Otherwise no user of your service can request it.
+          Right after this, your service might be queried and used by other
+          sessions, so you should not call setInit() prematurely.
+        </li>
+        <li>
+          You might provide a shutdown() method which is called when
+          Turbine shuts down. You can clean up your internal data in this
+          method. You should call setInit(false) as the last thing in
+          shutdown().
+        </li>
+      </ul>
+    </p>
+</section>
+
+<section name="Style">
+    <p>
+      It is good style, that if you build the FooService, to provide
+      <b>your.package.FooService.java</b> with an Interface definition of
+      your service which extends <b>org.apache.turbine.services.Service</b>
+      It should contain a constant SERVICE_NAME with the Turbine visible
+      name of your service like this:
+<source>
+package your.package;
+
+import org.apache.turbine.services.Service;
+
+public interface FooService extends Service
+{
+    /**
+     * The service identifier
+     */
+    public String SERVICE_NAME = "FooService";
+
+    [...]
+
+}
+</source>
+    </p>
+
+    <p>
+      <b>your.package.TurbineFooService.java</b> which extends the
+      <b>org.apache.turbine.services.TurbineBaseService</b> class and
+      implements <b>your.package.FooService</b> and provides the actual code:
+    </p>
+
+<source>
+package your.package;
+
+import org.apache.turbine.services.TurbineBaseService;
+
+public class TurbineFooService
+    extends TurbineBaseService
+    implements FooService
+{
+    /**
+     * Service logic here
+     */
+    [...]
+
+}
+</source>
+
+    <p>
+      <b>your.package.TurbineFoo.java</b> which contains static facade
+      methods for your service along the following lines:
+
+<source>
+import org.apache.turbine.services.TurbineServices;
+
+public class TurbineFoo
+{
+    protected static FooService getService()
+    {
+        return (FooService) TurbineServices
+            .getInstance().getService(FooService.SERVICE_NAME);
+    }
+
+    [...]
+
+    public static void fooMethod1()
+    {
+        getService().fooMethod1();
+    }
+
+    public static int fooMethod2(int bar)
+    {
+        return getService().fooMethod2(bar);
+    }
+
+    [...]
+
+}
+</source>
+    </p>
+
+    <p>
+      to give users of your service the ability to simply write:
+
+<source>
+TurbineFoo.fooMethod1();
+</source>
+    </p>
+
+    <p>
+      in their code and not to care about which actual Implementation of
+      FooService is running.
+    </p>
+
+    <p>
+      init() and shutdown() applies to Turbine 2-5 This might change
+      with the lifecycle interfaces in a later release.
+    </p>
+</section>
+
+ </body>
+</document>
diff --git a/src/site/xdoc/howto/url-mapper-howto.xml b/src/site/xdoc/howto/url-mapper-howto.xml
new file mode 100644
index 00000000..9387241d
--- /dev/null
+++ b/src/site/xdoc/howto/url-mapper-howto.xml
@@ -0,0 +1,256 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<document>
+
+ <properties>
+  <title>URL Mapper Howto</title>
+ </properties>
+
+<body>
+
+<section name="Introduction">
+
+<p>
+Unaltered Turbine URLs may look like this:
+<code>http://www.foo.com:8080/CONTEXT/servlet/MAPPING/template/Foo.vm</code>.<br/>
+But you want shorter URLs? Maybe this URL would suit you better:
+<code>http://www.foo.com:8080/CONTEXT/servlet/beautiful/world</code>
+</p>
+
+This HOWTO describes, how you can control the pathinfo or query part of a url (behind the webapproot and the context) and the context with a mapping (routing) file 
+defined in xml, json or yaml format to become more simplified or beautiful! 
+
+</section>
+
+<section name="Turbine URLMapper Configuration">
+
+<p>
+You need to
+<ul>
+<li>register the URL Mapper service in turbine configuration (TR.properties) </li>
+<li>register the valve in the pipeline (turbine-classic-pipeline.xml)</li>
+</ul> 
+</p>
+
+
+<p>Consider the following example configuration:
+
+MappedTemplateLink is for now optional, you can add it as a separate tool or just replace the existing TemplateLink.
+</p>
+
+<source><![CDATA[
+	# -------------------------------------------------------------------
+	#
+	#  U R L  M A P P E R  S E R V I C E
+	#
+	# -------------------------------------------------------------------
+	
+	# required
+	services.URLMapperService.classname=org.apache.turbine.services.urlmapper.TurbineURLMapperService
+	
+	# configFile is required here! xml, json and yml supported as extension.
+	services.URLMapperService.configFile = /conf/turbine-url-mapping.xml
+	
+	# new mapper (optional)
+	tool.request.mlink=org.apache.turbine.services.urlmapper.MappedTemplateLink
+	# tool.request.jlink= org.apache.turbine.services.pull.tools.TemplateLink
+]]></source>
+
+<p>To resolve a provided / mapped URL add the valve into pipeline (pipeline.default.descriptor = /conf/turbine-classic-pipeline.xml). 
+</p>
+
+<source><![CDATA[
+  <valves>
+    <valve>org.apache.turbine.services.urlmapper.URLMapperValve</valve>
+    ...
+
+]]></source>
+
+<p>This will check if the provided URL matches any pattern, resolves it given in the path or implicitly as defined in
+
+the URLMapperService's configfile.</p> 
+
+</section>
+
+<section name="Define your patterns">
+
+<p>The URL Mapping Mechanism uses a well defined pattern format. 
+The pattern format scheme is defined as follows, e.g. in JSON:</p>
+
+<source><![CDATA[
+ "pattern":  "/(?<webAppRoot>[.\\-\\w]+)/(?<contextPath>\\w+)/(?<resolvableParam>\\w+)/beautifulname"
+]]></source>
+
+<p>That is <strong>resolvableParam</strong> is just a specific parameter name or key, which should be resolved after the context slash and before the next URL part, which starts with "/beatifulname". 
+
+It  has to be set like this</p> 
+
+<source><![CDATA[
+ /(?<resolvableParam>\\w+)
+]]></source>
+
+Technically this isa non matching named group, with the group name <strong>resolvableParam</strong> and 
+
+in this case a sequence of alphabetical characters with minimal length of 1. 
+
+The same is true for the predefined <strong>webAppRoot</strong>  and <strong>contextPath</strong>. 
+
+<p>Another condition to be met, is that the parameter name must follow the "Java Named Group pattern characters restriction":</p>
+
+<source><![CDATA[
+ NAMED_GROUPS_PATTERN = Pattern.compile("(?<([a-zA-Z][a-zA-Z0-9]*)>.+?)");
+]]></source>
+
+<p>
+Any parameter is resolved as a <i>group name</i>
+ (<a href="https://docs.oracle.com/javase/8/docs/api/java/util/regex/Pattern.html">Java Pattern->Groups and Capturing->Group name</a>).
+ 
+These group names are predefined (symbolic group name)):
+ 
+<ul><li><strong>&lt;webAppRoot&gt;</strong></li><li><strong>&lt;contextPath&gt;</strong></li></ul>
+
+Be aware, that this does not allow replacing parameters containing other characters (e.g underscore or hyphens). You may use implicit parameter matching. 
+
+Following is an example for a configuration : 
+</p>
+
+<source><![CDATA[
+<url-mapping name="default">
+    <maps>
+        <map>
+            <pattern>/(?&lt;webAppRoot&gt;[.\\-\\w]+)/(?&lt;contextPath&gt;\w+)/book/(?&lt;bookId&gt;\d+)</pattern>
+            <implicit-parameters>
+                <parameter key="template">Book.vm</parameter>
+                <parameter key="detail">0</parameter>
+            </implicit-parameters>
+        </map>
+        ...
+]]></source>
+
+<p>Three parameters are evaluated:
+
+<ul><li>a parameter name <strong>template</strong> and value <strong>Book.vm</strong></li>
+<li>a parameter <strong>detail</strong> and value <strong>0</strong></li>
+<li>a parameter <strong>bookId</strong> with <i>any</i> value, e.g. <strong>4</strong></li>
+</ul>
+This will be converted, if matched, to an URL like <strong>/book/4</strong>. 
+The pattern uses type restrictions for the value, e.g. number for the bookId and a extended character set for the webAppRoot, which will be applied in (back resolving) <strong>mapFromURL</strong>.
+</p>
+
+<p>Another example in <strong>JSON</strong> format, which is much more readable, if not viewing in a browser is here (showing a shortened URL by replacing two parameters):</p>
+
+<source><![CDATA[
+{
+  "name": "default",
+  "maps": [
+	{
+		"pattern": "/(?<webAppRoot>[\\w]+)/(?<contextPath>\\w+)/register",
+		"implicit-parameters": {
+			"page": "Register",
+			"role": "anon"
+		}
+	},
+        ...
+]]></source>
+
+</section>
+
+<section name="Service Description">
+
+<p>The main methods of the service <strong>TurbineURLMapperService</strong> are</p> 
+
+<ul>
+<li><strong>mapToUrl</strong>, which as the Javadoc explains "maps a set of parameters (contained in TurbineURI PathInfo and QueryData) to a TurbineURIs"</li>
+<li><strong>mapFromUrl</strong>, which "maps a simplified URL to a set of parameters"</li>
+</ul> 
+
+  <subsection name="Matrix">
+      <table>
+        <tr>
+         <th colspan="6">Turbine URL Mapper Model</th>
+        </tr>
+        <tr>
+          <th>Mechanism</th><th>Method</th><th>Pattern</th><th>Implicit Param</th><th>Override Param</th><th>Ignore Param</th>
+        </tr>
+       
+        <tr><th>Converts Parameterized URL to simplified URL</th><th>mapToUrl</th><td>
+         "Match Group Name": The pattern of the target URL after evaluation of parameters. If a group name is set, a matching parameter key must be provided and the value will replace the group name in the target URL.</td>
+         <td>"Exact Filter", "Reduce": If a parameter key is is set implicitely, both key and value must exactly matched by a parameter pair in the provided (unmapped) URI. It will then be removed</td>
+         <td>- An override could be achieved by hard coding it in the pattern and filterign in implicit param. 
+         On the other hand you can then ignore the parameter</td>
+         <td>The parameter will be removed from the required parameter key set and also from the target URL if it is provided as a group name</td></tr>
+        
+        <tr><th>Resolves URL to Params for evaluating by the backend</th><th>mapFromUrl</th><td>
+        The pattern of the URL to be matched to evaluate parameter resolving</td>
+        <td>Param key/value will be set implicitely</td>
+        <td>Overrides (provided) URL parameter with provided value</td>
+        <td>will remove parameter key/value from result parameter list, even if provided as capturing group name</td></tr>
+      </table>
+    </subsection>
+    
+   <p>N.B. Symbolic group names <i>webAppRoot</i> and <i>context</i> could not be ignored or overridden!</p>
+   
+   
+</section>
+<section name="Usage">
+
+<p>
+Use the methods getRelative or getAbsoluteLink of the provided convenience class MappedTemplateLink class (of type TemplateLink) 
+in a velocity template like this:
+</p>
+
+<source><![CDATA[
+  
+  $mlink.addPathInfo("world","nice").getRelativeLink()
+  ## should result into a URL: /beautiful/world
+  
+]]></source>
+
+<p>
+<p>Alternatively you can use the service explicitely in Java, e.g. in a Java Action or other class if you inject the URLMapperService (or provide this in a shared  controller class).</p>
+
+<source><![CDATA[
+
+   // inside any assembler you may alternatively use annotation 
+   // @TurbineService( "URLMapperService" ) urlMapper;
+   
+   URLMapperService urlMapper = (URLMapperService) TurbineServices.getInstance().getService(URLMapperService.SERVICE_NAME);
+
+  // Any turbineURI ..e.g. from PoolService or 
+  TurbineURI uri  ... 
+          
+  urlMapper.mapToURL( uri );
+
+  
+  // use it, e.g by putting it into a velocity context (org.apache.velocity.context.Context(
+  context.put("myLink", link);
+     
+]]></source>
+
+ 
+More examples ...
+</p>
+
+
+</section>
+
+</body>
+</document>
diff --git a/src/site/xdoc/howto/url-rewriting-howto.xml b/src/site/xdoc/howto/url-rewriting-howto.xml
new file mode 100644
index 00000000..d2b5b94d
--- /dev/null
+++ b/src/site/xdoc/howto/url-rewriting-howto.xml
@@ -0,0 +1,187 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<document>
+
+ <properties>
+  <title>URL Rewriting Howto</title>
+ </properties>
+
+<body>
+
+<section name="Scenario and Overview">
+
+<p>
+Unaltered Turbine URLs look like this:
+<code>http://www.foo.com:8080/CONTEXT/servlet/MAPPING/template/Foo.vm</code>.<br/>
+But you want shorter URLs, or you don't like exposing the use of
+servlets in the URL.  Maybe this url would suit you better:
+<code>http://www.foo.com:8080/po/s/la/template/Foo.vm</code>
+</p>
+
+<p>
+The bulk of the url is defined by the servlet api and is outside of the
+control of Turbine:
+<pre>
+http://www.foo.com/CONTEXT/servlet/MAPPING/template/Foo.vm
+                   [ servlet api defined ][ turbine       ]</pre>
+
+This HOWTO describes how you can control the servlet part of the url
+in Tomcat.  For other servlet environments you'll have to consult
+their documentation.
+</p>
+
+<p>
+Three parts of the url will be addresed:
+<ol>
+<li>the web application context (CONTEXT in the example above),</li>
+<li>the servlet prefix (servlet),</li>
+<li>and the servlet mapping (MAPPING).</li>
+</ol>
+</p>
+
+</section>
+
+<section name="The Context">
+
+<p>
+You need to register the context with Tomcat. If you have given your
+application a short name like 'po' and placed it correctly in the
+webapps directory, then you won't need to do anything special. Tomcat
+will find the directory, and add a context. If you have a long
+application name like 'mywonderfulapp', add the following lines to
+Tomcat's server.xml file:
+</p>
+
+<source><![CDATA[
+<Context
+    path="/po"
+    docBase="webapps/mywonderfulapp"
+    reloadable="true"
+    debug="0"
+    trusted="false" >
+</Context>
+]]></source>
+
+<p>
+Everthing after the docBase= line is obviously up to you. This tells
+Tomcat to add a context named 'po' with the docbase of your
+application.
+</p>
+
+</section>
+
+<section name="The Servlet Prefix">
+
+<p>
+Modifying the servlet prefix also requires editing Tomcat's server.xml
+file.  Tomcat will use this prefix to determine if a given request is
+for a servlet.  Edit the following lines:
+</p>
+
+<source><![CDATA[
+<RequestInterceptor
+    className="org.apache.tomcat.request.InvokerInterceptor"
+    debug="0" prefix="/s/" />
+]]></source>
+
+<p>
+With this modification, Tomcat recognize requests containing /s/ in
+the url as a servlet request and will look for the servlet in the
+web.xml descriptor.
+</p>
+
+</section>
+
+<section name="The Servlet Name">
+<p>
+This is defined in web.xml (which you will find here:
+<code>webapps/WEB-INF/web.xml</code>).  This is automatically given
+the name of your application in Turbine.  To change it, simply edit the
+web.xml file as follows:
+</p>
+
+<source><![CDATA[
+<servlet-name>
+    la
+</servlet-name>
+]]></source>
+
+<p>
+<strong>If you are using Tomcat standalone, then you are done and your url is
+now <code>http://servername:port:/po/s/la</code></strong>
+</p>
+
+</section>
+
+<section name="If you are running Apache and mod_jk">
+
+<p>
+... you will need to change your mod_jk.conf file to include the following:
+</p>
+
+<source><![CDATA[
+#########################################################
+# Auto configuration for the /po context starts.
+#########################################################
+
+#
+# Make Apache aware of the location of the context
+#
+Alias /po "serverroot/webapps/mywonderfulapp"
+<Directory "serverroot/webapps/mywonderfulapp">
+     Options Indexes FollowSymLinks
+</Directory>
+
+#
+# Mount all JSP files and the /servlet/ uri to Tomcat
+#
+JkMount /po/s/* ajp12
+JkMount /po/*.jsp ajp12
+
+#
+# Prohibit users from directly accessing WEB-INF
+#
+<Location "/mywonderfulapp/WEB-INF/">
+     AllowOverride None
+     deny from all
+</Location>
+
+#
+# Prohibit users from directly accessing META-INF
+#
+<Location "/mywonderfulapp/META-INF/">
+     AllowOverride None
+     deny from all
+</Location>
+
+#######################################################
+# Auto configuration for the /po context ends.
+#######################################################
+]]></source>
+
+<p>
+document created August 14, 2001
+</p>
+
+</section>
+
+</body>
+</document>
diff --git a/src/site/xdoc/howto/velocity-site-howto.xml b/src/site/xdoc/howto/velocity-site-howto.xml
new file mode 100644
index 00000000..49d4d40f
--- /dev/null
+++ b/src/site/xdoc/howto/velocity-site-howto.xml
@@ -0,0 +1,560 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<document>
+
+ <properties>
+  <title>Velocity Site Howto</title>
+ </properties>
+
+<body>
+
+<section name="Velocity Site">
+
+<p>
+In Turbine, we have excellent integration with the template tool
+<a href="http://velocity.apache.org/">Velocity</a>,
+we call this VelocitySite building. The reason why we want to wrap Turbine
+around Velocity instead of using it on its own is to provide a completely
+MVC model for building web applications where the framework has control
+over the authentication, security, connection pool, etc and Velocity is
+simply used as the View portion of the MVC model. Turbine is responsible
+for helping you manage all the different templates as well so that you
+can easily construct a site that both designers and engineers can work
+together on (<strong>that is our primary goal!</strong>). The reason why this is
+good is that it will help you design and build web applications that have
+more functionality and less duplication of code since Turbine is fully
+re-usable.
+</p>
+
+<p>
+Knowledge of how Velocity works and what a Velocity Context object is
+are required for understanding this documentation. This documentation also
+assumes that you are using a Servlet API 2.2 and higher servlet engine
+such as <a href="http://tomcat.apache.org/">Tomcat</a> because
+we are now targeting towards using WAR archives. Although, this should
+work with older servlet engines as well...it just may be slightly harder
+for you to setup. You should also be familiar with the rest of the Turbine
+documentation that is referenced on the <a href="index.html">index page</a>.
+</p>
+
+<p>
+Here is a brief description of the way that the system works: all requests
+are passed through the Turbine Servlet. The servlet is then responsible
+for brokering the request, building up the Context object and then calling
+Velocity's template engine to process your template document and return
+the results. Pretty simple. Now, lets move on to some more detailed instructions...:-)
+</p>
+
+</section>
+
+<section name="Screens">
+
+<p>
+Lets start off with a simple Velocity Screen to get things rolling
+so you can see how powerful things are. You should compile this class into
+your <em>WEB-INF/classes</em> directory.
+</p>
+
+<p>
+Note: In the examples below, you should replace <code>com.yourcompany.app</code>
+with the correct value for your application.
+</p>
+
+<source>
+package com.yourcompany.app.modules.screens;
+
+// Velocity Stuff
+import org.apache.velocity.context.Context;
+
+// Turbine Stuff
+import org.apache.turbine.util.RunData;
+import org.apache.turbine.modules.screens.VelocityScreen;
+
+public class HelloWorld extends VelocityScreen
+{
+    public void doBuildTemplate( RunData data, Context context )
+        throws Exception
+    {
+        // the context object has already been setup for you!
+        context.put ("hello", "this is a test...");
+    }
+}
+</source>
+
+<p>
+Ok, as you can see, you do not even need to return a value from your method!
+You simply stuff objects into the Velocity Context and that is it! Next,
+you will want to create a .vm template of the same name as your class:
+HelloWorld.vm...within that template you will put the BODY portion of your
+page. In other words, there is no reason to put the header/footer into
+this file since that will be built seperately (more documentation on that
+futher down...). You should save this document in your <em>templates/screens/</em>
+directory.
+</p>
+
+<p>
+You will also need to modify your TurbineResources.properties file to tell
+Turbine where to look for your new screen class.
+</p>
+
+<source>
+module.packages=org.apache.turbine.modules, com.yourcompany.app.modules
+</source>
+
+<source><![CDATA[
+<p>
+    <font color="red">
+        $hello of the emergency broadcast station.
+    </font>
+</p>
+]]></source>
+
+<p>
+When you request a URL like this:
+</p>
+
+<p>
+http://www.server.com/servlet/Turbine/template/HelloWorld.vm
+</p>
+
+<p>
+What that will do is cause the system to first execute the HelloWold.java
+class (if it exists) and then it will call Velocity's template engine directly
+and execute the HelloWorld.vm template and then return the results back
+to you.
+</p>
+
+<p>
+<em>NOTE:</em> Turbine capitalizes the first letter in the class file name
+before looking for the matching class in the classpath.  This allows you to
+follow (somewhat) normal class naming guidelines. For example:
+</p>
+
+<p>
+index.vm and Index.vm both map to Index.class
+
+roleeditor.vm maps to Roleeditor.class
+
+role_editor.vm maps to Role_editor.class
+</p>
+
+<p>
+The result will be a fully formed HTML document with the <em>$hello</em>
+replaced with the value: "this is a test...". If you want to make the URI
+above shorter or easier to read, you could simply re-write things using
+<a href="http://httpd.apache.org/docs/current/mod/mod_rewrite.html">mod_rewrite</a>.
+For example, by removing the "<em>/servlet/Turbine/template</em>" portion
+of the URI.
+</p>
+
+<p>
+As you can see, this is much easier than doing servlet after servlet
+because it removes a lot of the setup and other things that could potentially
+go wrong. It also makes the individual template files easier to manage
+and more re-usable because there isn't any surrounding page layout mixed
+in with the page.
+</p>
+
+<p>
+If you want to do something that is more complicated than this that
+is reflected across all of your Screens, then you should write a class
+that is a subclass of VelocityScreen and then put your specific code
+in there. For example, if you wanted a security method to be called automaticially
+without having to normally call super() to get it from an overridden method
+in the superclass, you could have something like this (semi-pseudo untested
+code):
+</p>
+
+<source>
+package com.yourcompany.app.modules.screens;
+
+// Velocity Stuff
+import org.apache.velocity.context.Context;
+
+// Turbine Stuff
+import org.apache.turbine.util.RunData;
+import org.apache.turbine.modules.screens.VelocityScreen;
+
+public abstract class SecureScreen extends VelocityScreen
+{
+    protected boolean doCheckSecurity(RunData data)
+        throws Exception
+    {
+        if (data.isSecure())
+            return true;
+        else
+            return false;
+    }
+
+    /*
+     * override the doBuild() method of the
+     * TemplateScreen to always check security first
+     */
+    public void doBuild(RunData data, Context context) throws Exception
+    {
+        if ( !this.doCheckSecurity(data))
+        {
+            // set the template and screen to be different or do
+            // some other short circuit code here
+        }
+        doBuildTemplate(data, context);
+        return super.buildTemplate(data, context);
+    }
+}
+</source>
+
+<p>
+What this would do is override the doBuild() method in TemplateScreen (which
+is the base class that VelocityScreen subclasses from) and have it
+always do a security check before displaying the content. The benefit of
+this is that all you need to do to add security to your screen is to simply
+subclass this class instead of VelocityScreen. There is also no need
+to remember to call super() since the doBuild() method will be called for
+you automatically by Turbine. You can start to see how Turbine is simply
+an extension of the servlet framework itself. For example, the Servlet
+Engine will call HttpServlet's service() method for you, just like Turbine
+will call your doBuild() method for you. Tight integration with tools like
+Velocity just make things even cleaner. :-)
+</p>
+
+<p>
+One other feature in this system is that if you are not building up
+a Context object that is specific for your screen, then you do not need
+to create a Java class to match the template file. You simply create the
+.vm template and put it in a directory and call it with the same URI described
+above. This is really useful when you have a static site of content that
+you are converting to be dynamic and you only want to do small portions
+of it at any one time. You can also do the opposite of this which is to
+only create a Java class file and no template file. You can do this by
+simply overriding the doBuild() method in TemplateScreen and returning
+your results directly instead of attempting to build a template. Later,
+when you want to add a template and remove the HTML code, you can change
+the doBuild() into a doBuildTemplate(), build the Context object up and
+you are done. Cool!
+</p>
+
+<p>
+Here is an example of having templates in subdirectories and making
+links to each of them.
+</p>
+
+<p>
+Create a directory structure like this:
+</p>
+
+<p>
+WEB-INF/templates/screens/admin/
+Put <em>index.vm</em> into the <em>screens/</em> directory.
+Put <em>UserAdmin.vm</em> into the <em>screens/admin/</em> directory.
+</p>
+
+<p>
+In index.vm, if you want to link to UserAdmin.vm, you would add something
+like this to the HTML:
+</p>
+
+<source><![CDATA[
+<a href="$link.setPage("admin,UserAdmin.vm")">User Admin Screen</a>
+]]></source>
+
+<p>
+As you can see above, I used a "," instead of a "/".  The above will create
+a fully formed URI with the session information encoded into the link if the \
+client browser has cookies turned off.
+</p>
+
+<p>
+    If you really want to use a slash instead of the comma when using the $link
+    tool, you will need to make a change to your TurbineResources.properties
+    file.  You need to change the value of <code>tool.request.link</code> from
+    <code>org.apache.turbine.util.template.TemplateLink</code> to
+    <code>org.apache.turbine.util.template.TemplateLinkWithSlash</code>.
+</p>
+<p>
+    You will incur a slight performance hit since this class will replace the
+    slash for with a comma for you.  The URL that is build as a result will be
+    identical.
+</p>
+
+
+
+</section>
+
+<section name="Layout and Navigations">
+
+<p>
+Now that you know how to create simple Screens, you are probably wondering
+where the layout and navigation portions of the page come from and how
+you control that. If you were not wondering that, then shame on you. :-)
+Essentially, it is the same exact procedure as before except you subclass
+VelocitySiteLayout and VelocitySiteNavigation instead. Again, it is possible
+to not have Java class files always match up with the template and in most
+cases, you probably won't need to have a user defined Context in the Layout.
+</p>
+
+<p>
+Below is an example Layout. It will be searched for in the templates/layouts
+directory structure and also takes advantage of the same template path
+lookup code as described below:
+</p>
+
+<source><![CDATA[
+#if($data.Message)
+    $data.Message
+#end
+
+<table width="100%">
+
+<tr>
+    <td>$navigation.setTemplate("/default_top.vm")</td>
+</tr>
+<tr>
+    <td>$screen_placeholder</td>
+</tr>
+<tr>
+    <td>$navigation.setTemplate("/default_bottom.vm")</td>
+</tr>
+
+</table>
+]]></source>
+
+<p>
+The variable <em>$screen_placeholder</em> is important here because that
+is where the output from your Screen will be placed. VelocitySiteLayout
+is responsible for taking care of this. The other variables are for including
+your Navigations into the system. The benefit of all of this is that it
+enforces the View portion of the MVC model because the "body" and "navigation"
+portions of your page simply becomes a variable that you can plug into
+any number of Layouts and in any location. If you want to write code so
+that the Layout is determined by a variable in the database or in the HTTP
+request or whever, all you need to do is write your own VelocitySiteLayout
+and override some of the methods in there to determine the layout based
+on your own conditions instead of the system default conditions.
+</p>
+
+
+</section>
+
+<section name="How the templates are found">
+
+<p>
+Since everything is keyed off the template variable, if
+<em>data.getParameters().getString("template")</em>
+returns <em>/about_us/directions/driving.vm</em>, the search for the Screen
+class is as follows (in order):
+</p>
+
+<ol>
+<li>about_us.directions.Driving</li>
+
+<li>about_us.directions.Default</li>
+
+<li>about_us.Default</li>
+
+<li>Default</li>
+
+<li>VelocityScreen</li>
+</ol>
+
+<p>
+If the template variable does not exist, then <em>VelocityScreen</em>
+will be executed and <em>templates/screens/index.vm</em> will be executed.
+If <em>index.vm</em> is not found or if the template is invalid or Velocity
+execution throws an exception of any reason, then <em>templates/screens/error.vm</em>
+will be executed.
+</p>
+
+<p>
+For the Layouts and Navigations, the following paths will be searched
+in the layouts and navigations template subdirectories (in order):
+</p>
+
+<ol>
+<li>/about_us/directions/driving.vm</li>
+
+<li>/about_us/directions/default.vm</li>
+
+<li>/about_us/default.vm</li>
+
+<li>/default.vm</li>
+</ol>
+
+</section>
+
+<section name="Actions">
+
+<p>
+Actions happen when you have an <em>action</em> parameter defined in the
+URI. For example:
+</p>
+
+<p>
+<ul><u>http://www.server.com/servlet/Turbine/template/HelloWorld.vm/action/UpdateWorld</u></ul>
+</p>
+
+<p>In this case, what happens is that the class UpdateWorld class (located in your
+<em>WEB-INF/classes/com/yourcompany/app/modules/actions/</em> directory)
+is executed first before
+anything. Then your HelloWorld class (located in your
+WEB-INF/classes/com/yourcompany/app/modules/screens/
+directory) is executed. Then your template (for screen/navigation/layout)
+HelloWorld.vm is executed. The point of an action is that it should perform
+some sort of "action" on your system. Usually, this means storing some
+information from a POST request into a database or sending email or something
+of that nature. Actions themselves do not return results, but may set a
+message with data.setMessage(). They can also short circuit the system
+by changing the Template and Screen to be executed. You might want to do
+that if there is an error with the form data and you want to re-display
+the same page again. Unlike most of the rest of the modules (ie: Screens,
+Navigations, Layouts), there is no corresponding Velocity template file
+for an Action.
+</p>
+
+<source>
+package com.yourcompany.app.modules.actions;
+
+// Velocity Stuff
+import org.apache.velocity.context.Context;
+
+// Turbine Stuff
+import org.apache.turbine.util.RunData;
+import org.apache.turbine.modules.actions.VelocityAction;
+
+public class AddUser extends VelocityAction
+{
+    public void doPerform( RunData data, Context context ) throws Exception
+    {
+        if ( data.getParameters().getString("username",null) == null)
+        {
+            data.setMessage("Username does not exist");
+            setTemplate ( data, "AddUser.vm" );
+            return;
+        }
+
+        // store user info into database
+        data.setMessage("Information stored!");
+        setTemplate( data, "MainMenu.vm");
+
+        // stuff something into the Velocity Context
+        context.put ("variable", "foo");
+    }
+}
+</source>
+
+<p>
+In the very basic example Action above, a check is performed to make sure
+that
+the form data contained a "username" variable. If there is no data, the
+template is changed back to the "AddUser" template and the processing is
+stopped with an error message that can be easily displayed in the template.
+If the processing finishes, then the MainMenu.vm template will be shown
+and the message can be displayed.
+</p>
+
+</section>
+
+<section name="Action Event">
+
+<p>
+There is also a new feature of Turbine that the VelocitySiteAction takes
+advantage of, it is called <a href="action-event-howto.html">Action Event</a>.
+Please click the link and read more documentation about it. This is an
+excellent way to write your actions because now they are entirely event
+driven based on which button was clicked in the HTML form.
+</p>
+
+</section>
+
+<section name="Velocity Frames">
+
+<p>
+Frames are easily achieved with Velocity, the frameset tag being implemented at
+the screen level. The default setting for the layout.default directive in the
+TurbineResources.properties is the VelocityECSLayout class.
+The VelocityECSLayout wraps the Screen in Body tags. For frames this needs to be
+removed. The layout.default needs to be changed to;
+</p>
+
+<source>
+layout.default=VelocityOnlyLayout
+</source>
+
+<p>
+The layout Velocity template needs to point to the screen_placeholder. As an
+example modify the Default.vm in the /WEB-INF/templates/layouts/;
+</p>
+
+<source>
+$screen_placeholder
+</source>
+
+<p>
+The screen_placeholder marker will load and process the template marked as the
+template.homepage in the TurbineResources.properties. To create frames this is
+the template which will need to contain the frameset tag. Edit
+/WEB-INF/templates/screens/Index.vm;
+</p>
+
+<source><![CDATA[
+$page.setTitle("Frames example");
+
+<frameset>
+  <frame src="$link.getPage("FrameTop.vm")" />
+  <frame src="http://www.something.com/" />
+</frameset>
+]]></source>
+
+<p>
+Create a FrameTop.vm template in the /WEB-INF/templates/screens directory. The
+top frame will load this template. The reference to something.com requires an
+internet connection and is shown as an example, anything can be linked to the
+lower frame, another Velocity Screen for instance.
+</p>
+
+<source><![CDATA[
+## Example FrameTop.vm
+<p><b>The FrameTop Velocity Template</b>
+]]></source>
+
+</section>
+
+<section name="Multiple Velocity Paths">
+
+<p>
+The VelocityService can support many paths for the Velocity Templates to
+be loaded and read from. This is specified in the
+TurbineResources.properties file;
+</p>
+
+<source>
+services.VelocityService.file.resource.loader.path = /templates,/my-templates,/more-tempates
+</source>
+
+<p>
+The multiple paths are comma delimited and are specified from the
+Servlet Engines context.
+</p>
+
+</section>
+
+</body>
+</document>
+
diff --git a/src/site/xdoc/howto/velocityonlylayout-howto.xml b/src/site/xdoc/howto/velocityonlylayout-howto.xml
new file mode 100644
index 00000000..e9f69c80
--- /dev/null
+++ b/src/site/xdoc/howto/velocityonlylayout-howto.xml
@@ -0,0 +1,231 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<document>
+
+ <properties>
+  <title>VelocityOnlyLayout</title>
+ </properties>
+
+<body>
+
+<section name="Introduction">
+<p>
+    The VelocityECSLayout has been deprecated in Turbine 2.3. This document
+    is intended to help you convert your application to use the
+    VelocityOnlyLayout.
+</p>
+<p>
+    The VelocityOnlyLayout does not use ECS to generate the HTML page for
+    you. This also means that the current $page pull tool will not work with
+    the VelocityOnlyLayout. You will be responsible for constructing the HTML,
+    HEAD, BODY, etc. tags using Velocity.
+</p>
+<p>
+    Although this seems like a lot of trouble, it really isn't. All that you
+    really need to do is modify your layout templates. You will still use the
+    $page pull tool just like before. Your layout templates will also use the
+    $page pull tool to extract the data needed to build the HEAD and BODY
+    tags.
+</p>
+</section>
+
+<section name="Changes to make in TR.props">
+<p>
+    Changes the definition of the $page pull tool:
+</p>
+<source>
+<![CDATA[
+tool.request.page = org.apache.turbine.util.template.HtmlPageAttributes
+]]>
+</source>
+<p>
+	Change the default layout
+</p>
+<source>
+<![CDATA[
+services.VelocityService.default.layout = VelocityOnlyLayout
+]]>
+</source>
+
+</section>
+
+<section name="Changes to your code">
+<p>
+  <ul>
+  	<li>$page.addAttribute(attribute,value) has been replaced with
+  	    $page.addBodyAttribute(attribute,value)</li>
+  	<li>$page.setScript(url) has been replaced with
+  	    $page.addScript(url)</li>
+  	<li>$page.setStyleSheet(url) has been replaced with
+  	    $page.addStyleSheet(url)</li>
+  	<li>$page.setStyle(styleText) has been replaced with
+  	    $page.addStyle(styleText)</li>
+  	<li>$page.setStyleSheet(url,media) has been replaced with
+  	    $page.addStyleSheet(url,media,title,type)</li>
+  </ul>
+</p>
+<p>
+    <em>Use of any of the deprecated methods will generate a log message
+    at the info level.</em>
+</p>
+<p>
+    Add the line
+</p>
+<source>
+<![CDATA[
+$page.DefaultDoctype
+]]>
+</source>
+<p>
+    to your layout templates to pick up the default doctype definition from
+    TurbineResources.properties thus:
+</p>
+<source>
+<![CDATA[
+# Set the components of the default Doctype for use in html documents.
+#
+# Defaults: There are no defaults - if default.html.doctype.root.element is not
+#           set then no default doctype will be available.
+
+default.html.doctype.root.element=HTML
+default.html.doctype.identifier=-//W3C//DTD HTML 4.01 Transitional//EN
+default.html.doctype.url=http://www.w3.org/TR/1999/REC-html401-19991224/loose.dtd
+]]>
+</source>
+<p>
+    Add the line
+</p>
+<source>
+<![CDATA[
+services.VelocityService.velocimacro.library = macros/TurbineMacros.vm
+]]>
+</source>
+<p>
+    to your TurbineResources.properties and it will pick up the
+    TurbineMacros.vm in your Turbine jar. An example of how to use
+    these macros follows.
+</p>
+<p>
+    Here is a sample layout template that you can use:
+</p>
+<source>
+<![CDATA[
+    ## Set defaults for all pages using this layout.  Anything set here can
+    ## be overridden in the screen template.
+    $page.setTitle("My default page title");
+    $page.setHttpEquiv("Content-Style-Type","text/css")
+    $page.addStyleSheet($content.getURI("myStyleSheet.css"))
+    $page.addScript($content.getURI("globalJavascriptCode.js"))
+    ## build the HTML, HEAD, and BODY tags dynamically
+
+    $page.DefaultDoctype
+    <html>
+      #TurbineHtmlHead()
+      <body #TurbineHtmlBodyAttributes() >
+      $navigation.setTemplate("default_header.vm")
+      $screen_placeholder
+      $navigation.setTemplate("default_footer.vm")
+
+      </body>
+    </html>
+]]>
+</source>
+<p>
+    This produces the same code as the following sample layout
+    template that you can use:
+</p>
+	<source>
+<![CDATA[
+    ## Set defaults for all pages using this layout.  Anything set here can
+    ## be overridden in the screen template.
+    $page.setTitle("My default page title");
+    $page.setHttpEquiv("Content-Style-Type","text/css")
+    $page.addStyleSheet($content.getURI("myStyleSheet.css"))
+    $page.addScript($content.getURI("globalJavascriptCode.js"))
+    ## build the HTML, HEAD, and BODY tags dynamically
+
+    $page.DefaultDoctype
+    <html>
+      <head>
+        #if($page.Title != "")
+        <title>$page.Title</title>
+        #end
+        #foreach($metaTag in $page.MetaTags.keySet())
+        <meta name="$metaTag" content="$page.MetaTags.get($metaTag)">
+        #end
+        #foreach($httpEquiv in $page.HttpEquivs.keySet())
+        <meta http-equiv="$httpEquiv" content="$page.HttpEquivs.get($httpEquiv)">
+        #end
+        #foreach($styleSheet in $page.StyleSheets)
+          <link rel="stylesheet" href="$styleSheet.Url"
+            #if($styleSheet.Type != "" ) type="$styleSheet.Type" #end
+            #if($styleSheet.Media != "") media="$styleSheet.Media" #end
+            #if($styleSheet.Title != "") title="$styleSheet.Title" #end
+          >
+        #end
+        #if ($page.Styles.size() > 0)
+          <style type="text/css">
+          #foreach( $style in $page.Styles )
+            $!style
+          #end
+          </style>
+        #end
+        #foreach($script in $page.Scripts)
+          <script type="text/javascript" src="$script" language="JavaScript"></script>
+        #end
+      </head>
+
+      ## Construct the body tag.  Iterate through the body attributes to build the opening tag
+      <body
+        #foreach($attributeName in $page.BodyAttributes.keySet())
+          $attributeName = "$page.BodyAttributes.get($attributeName)"
+        #end
+      >
+
+      $navigation.setTemplate("default_header.vm")
+      $screen_placeholder
+      $navigation.setTemplate("default_footer.vm")
+
+      </body>
+    </html>
+]]>
+</source>
+</section>
+
+<section name="Writing Directly To ServletOutputStream">
+<p>
+    See
+	<a href="http://wiki.apache.org/turbine/Turbine2/VelocityOnlyLayout">
+	VelocityOnlyLayout</a> on the Turbine wiki for some information concerning
+	writing directly to ServletOutputStream.
+</p>
+</section>
+
+<section name="Updates to this document">
+<p>
+    This document is by no means complete or totally accurate. We welcome
+    suggestions as to how it might be improved, particularly if you have
+    just completed updating an application by following this howto.
+</p>
+</section>
+
+</body>
+</document>
diff --git a/xdocs/index.xml b/src/site/xdoc/index.xml
similarity index 98%
copy from xdocs/index.xml
copy to src/site/xdoc/index.xml
index 61d4f180..4a513480 100644
--- a/xdocs/index.xml
+++ b/src/site/xdoc/index.xml
@@ -21,7 +21,7 @@
 <document>
 
  <properties>
-  <title>Apache Turbine&#8482;</title>
+  <title>Apache Turbine&trade;</title>
  </properties>
 
  <body>
@@ -29,7 +29,7 @@
  <section name="What is Apache Turbine?">
  
  <p>
-    Apache Turbine&#8482; is a servlet based framework that allows experienced Java
+    Apache Turbine is a servlet based framework that allows experienced Java
     developers to quickly build secure web applications. Parts of
     Turbine can also be used independently of the web portion of Turbine
     as well. In other words, we strive to make portions of Turbine
diff --git a/src/site/xdoc/j2ee-integration.xml b/src/site/xdoc/j2ee-integration.xml
new file mode 100644
index 00000000..625212a2
--- /dev/null
+++ b/src/site/xdoc/j2ee-integration.xml
@@ -0,0 +1,205 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<document>
+
+ <properties>
+  <title>J2EE Integration</title>
+ </properties>
+
+<body>
+
+<section name="J2EE Integration">
+
+<p>
+This document serves to answer a few common questions about integration
+of Turbine with J2EE technologies including Servlets, EJB, Swing, JMS,
+Transactions, JNDI, XML, JDBC, JSP, and Security. The short answer is
+that it is all Java code and you can choose to use Turbine's solutions
+to some things or you can choose to use J2EE solutions to some things.
+Turbine is increasingly flexible about what parts you choose to use and
+what parts you don't. The reason is because there has been quite a lot
+of de coupling of the various Turbine components as a result of years of
+development and use by people all over the world in various different
+ways. Wow, isn't that cool?
+</p>
+
+<subsection name="How does Turbine work with ... ?">
+<table>
+  <tr>
+    <td>Servlets</td>
+    <td>
+<p>
+It is a servlet. It is also a set of re-usable components assembled into
+a framework. You can choose to work with just the Servlet, you can
+choose to work with just the components or you can choose to work with
+both. In a lot of normal development cases, people start off with a
+simple servlet and tack on various components (like Connection Pooling,
+Cron Schedulers, User Management, Services, etc.). That is what we have
+done as well, however we have done it in such a way that it is very
+pluggable. Mix and match and use what you want to use. Ignore the rest.
+</p>
+    </td>
+  </tr>
+  <tr>
+    <td>EJB</td>
+    <td>
+<p>
+Turbine provides a framework for developing web applications -
+specifically the front end. EJB provides a framework for developing
+n-tier applications - specifically the back ends - thus Turbine and EJB
+complement each other well at that level.
+</p>
+    </td>
+  </tr>
+  <tr>
+    <td>Swing</td>
+    <td>
+<p>
+Turbine is the for the web - Swing is not - not applicable.
+</p>
+    </td>
+  </tr>
+  <tr>
+    <td>JMS</td>
+    <td>
+<p>
+Turbine provides facilities for plugging in other Services - and thus
+JMS could be plugged in as a service to that. Even if it isn't plugged
+in through Turbine's Services facilities, you can still put your JMS
+related methods into your code. Turbine doesn't prevent you from calling
+other Java code.
+</p>
+    </td>
+  </tr>
+  <tr>
+    <td>Transactions</td>
+    <td>
+<p>
+There is nothing in Turbine explicitly using the JTS/JTA - but can use
+EJB and hence these technologies. That belongs in EJB's anyways. :-)
+</p>
+    </td>
+  </tr>
+  <tr>
+    <td>JNDI</td>
+    <td>
+<p>
+Turbine provides access to JNDI via a Service facility. You can always
+choose to implement your own facility as well (ie: if you have an
+existing code base that you would like to use, Turbine does not stop you
+from using it).
+</p>
+    </td>
+  </tr>
+  <tr>
+    <td>XML</td>
+    <td>
+<p>
+Turbine provides support for using and working with XML. Again, nothing
+preventing you from using XML within Turbine or even sending XML out
+of Turbine.
+</p>
+    </td>
+  </tr>
+  <tr>
+    <td>JDBC</td>
+    <td>
+<p>
+Turbine provides good support for working with JDBC through the <a
+href="http://db.apache.org/torque/">Village API</a>, the <a
+href="http://db.apache.org/torque/user-guide.html">
+Torque Object Relational Tool</a> and its connection
+pooling facilities. The connection pool is not yet fully J2EE
+"compatible" in that it does not support DataSources. However, at some
+point we may choose to implement that. Note, again, Turbine does not
+prevent you from using your own Connection pooling mechanism, we simply
+created one because at the time, we needed one and ours works just fine.
+</p>
+    </td>
+  </tr>
+  <tr>
+    <td>JSP</td>
+    <td>
+<p>
+Turbine provides excellent support for using JSP in its model of working
+- which is based on the Model 2 style with enhancements, such as solving
+the Action portion of the Model. However, we <a
+href="http://velocity.apache.org/ymtd/ymtd.html">strongly
+suggest</a> that you do not use JSP and seek out other alternatives.
+</p>
+    </td>
+  </tr>
+  <tr>
+    <td>Security</td>
+    <td>
+<p>
+Turbine was created long before J2EE was created. Therefore, we needed
+to implement our own Security Model. This model is based on Users,
+Roles, Permissions and Object Groups. It is an Access Control List (ACL)
+based security scheme and can grow to support nearly any level of access
+control people can come up with. It follows our extensible design
+pattern and you can use Turbine's code as the basis for any additional
+security your application requires.
+</p>
+    </td>
+  </tr>
+  <tr>
+    <td>Container Managed Security</td>
+    <td>
+<p>
+You can use container managed security if you wish, and Turbine provides you with
+mechanism for application manged security, in case you need them.
+</p>
+<p>
+The main problem with container managed security is that it cannot be managed
+from the inside of the application. Whenever you want to add/remove users to
+your application (or suite of them) or want to modify user's roles, you need
+to use whatever tool your application server provides for that.
+</p>
+<p>
+Now, this could work just fine for closed-public applications and intranets,
+but would be really unacceptable on open-public sites, where the users need
+the ability to register and receive 'accounts' without human interaction.
+</p>
+<p>
+Currently Turbine supports the latter model - application managed security.
+This is because if it didn't have it, many people would have to write code
+to provide it. That's why we created SecurityService in a cooperative effort.
+</p>
+<p>
+On the other hand, you don't need to write any code to use declarative
+container managed security. You can restrict access to the Turbine
+servlet with the usual web.xml magic. If you wish to use programmatic
+container managed security code, there is relatively very little code to write.
+You need to create your own SecureScreens (probably extending VelocityScreen)
+and SecureActions that contained code that calls the <code>HttpServletRequest
+getUserPrincipal</code> and <code>isUserInRole</code> methods.
+above.
+</p>
+    </td>
+  </tr>
+</table>
+</subsection>
+
+</section>
+
+</body>
+</document>
diff --git a/src/site/xdoc/model2+1.xml b/src/site/xdoc/model2+1.xml
new file mode 100644
index 00000000..cd4bbd19
--- /dev/null
+++ b/src/site/xdoc/model2+1.xml
@@ -0,0 +1,125 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<document>
+
+ <properties>
+  <title>Turbine Model 2+1</title>
+ </properties>
+
+<body>
+
+<section name="What is model 2+1?">
+
+<source test=""><![CDATA[
+   To: turbine@list.working-dogs.com
+   Subject: Re: Is Turbine MVC or HMVC?
+   Date: Wed, 11 Oct 2000 14:04:52 +0200
+   From: Christoph Reck Christoph.Reck@dlr.de
+]]></source>
+
+<p>
+Turbine follows the MVC design pattern.
+</p>
+<p>
+<ul>
+<li>  Model      - the underlying data sources (via peers or beans)</li>
+<li>  View       - one of the templating engines</li>
+<li>  Controller - Turbine servlet plus your action+screen classes</li>
+</ul>
+</p>
+
+<p>
+Since the view and the controller are tightly coupled in Turbine,
+it is stated to follow the Model2 design pattern, with a + 1
+addition due to way actions are used (hence Model 2 + 1).
+</p>
+
+<p>
+Turbine does not directly support the Hierarchical MVC pattern, but
+it could be used this way by defining multiple module and template
+paths (would impact performance). Note that in the HMVC each MVC
+instance is self-contained and separable from the rest.
+</p>
+
+<p>
+Note that many components within a MVC system follow themselves
+the MVC pattern, therefore most MVC systems are also HMVC systems
+(this also applies to Turbine as a whole, but your application with
+Turbine is normally not HMVC).
+</p>
+
+<p>
+Also note that you could use Turbine in a non MVC manner, but
+normally it leads you to use it as MVC (which JSP does not).
+</p>
+
+<p>
+I hope this clarifies your question,
+Christoph
+</p>
+
+</section>
+
+<section name="Jon's Comments">
+<p>
+That is a GREAT explanation and I'm going to use that for now on...except it
+isn't entirely true. :-)
+</p>
+
+<p>
+The +1 was a joke on my part to see what people would do with it. I figured
+that people were believing this Model 2 hype with JSP and such and I wanted
+to improve on it. I love playing with marketing games. I read that Model 2
+paper and then figured that Turbine was better than what they declared as
+Model 2.
+</p>
+
+<p>
+Calling it Model 3 would have been like saying that Turbine was just a third
+generation of Model 2. So, instead I figured that making it +1 just made it
+appear to be an improved Model 2 model since that is what Turbine really is.
+:-)
+</p>
+
+<p>
+Oh yea...one more reason for the +1...
+</p>
+
+<p>
+It is the Apache <a href="http://jakarta.apache.org/site/decisions.html">voting style</a>. :-)
+</p>
+
+<p>
+Turbine is Model 2 .......... +1 ! :-)
+</p>
+
+<p>-jon stevens</p>
+</section>
+
+<section name="Resources">
+<p>
+<a href="http://www.javaworld.com/javaworld/jw-12-1999/jw-12-ssj-jspmvc.html">
+Understanding JavaServer Pages Model 2 architecture</a>
+</p>
+
+</section>
+</body>
+</document>
diff --git a/src/site/xdoc/project-map.xml b/src/site/xdoc/project-map.xml
new file mode 100644
index 00000000..5a58d6a7
--- /dev/null
+++ b/src/site/xdoc/project-map.xml
@@ -0,0 +1,153 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<document>
+
+    <properties>
+        <title>Project Map</title>
+    </properties>
+
+    <body>
+
+    <section name="Project Map">
+
+    <p> On this page, you can find a functional breakdown of Turbine codebase.
+    This should help you in getting familiar with the tools that Turbine offers
+    to you. Also, it will help you locate people that are experts in the field
+    of a specific functional block, so you can contact them if you encounter
+    a problem, or better yet have made a patch that fixes it. </p>
+
+    <p><a href="project-map/core.html"><b>Turbine Core</b></a></p>
+
+    <p> In the Core part of Turbine you will find the Turbine Servlet, the
+    single entry point to your application, and the classes that form the
+    framework of HTTP-interfaced application following MVC design pattern.
+    Here you will find the base classes you will have to extend to fill
+    in the framework with your application's logic. See the
+    <a href="fsd.html">specification</a> for more details. </p>
+
+    <p><a href="project-map/essential.html"><b>Essential Services</b></a></p>
+
+    <p> This block contains the <a href="services.html">Service Framework</a>
+    that forms the basis of  Turbine infrastructure. It allows defining
+    utility classes with pluggable implementation (that means that you
+    can customize and  override the utility classes provided by Turbine
+    easily) that can take part in the startup and shutdown sequence of the
+    application. </p>
+
+    <p><a href="project-map/content-generation.html"><b>Content generation services</b></a></p>
+
+    <p> This block groups together various services that aid you in the process
+    of creating the user interface of your application. Most important,
+    you will find here services that provide <i>templating</i> functionality,
+    that allows you to create the HTML/XML/WML presentation layer of your
+    application independently form your Java sources. The services provided
+    are actually wrappers around templating packages developed independently
+    from Turbine, such as <a href="http://velocity.apache.org">Velocity</a>.
+    Also, there is a service that allows you to use Sun's JSP technology for
+    creating templates. Other services that fall into this block are
+    the Pull service, allowing you to create tool boxes (read more about
+    <a href="pullmodel.html">Pull model</a>), Localization service, that allows
+    you to crate bundles of messages that your application displays translated
+    into different languages, that can be easily manipulated, and the
+    Upload service, that handles uploading files from HTML forms. </p>
+
+    <p><a href="project-map/database.html"><b>Database access</b></a></p>
+
+    <p> Database tools in Turbine include connection pooling service, which
+    can transparently delegate to J2EE application server's pooling facilities,
+    of provide connection pooling in lightweight, servlet container only
+    environment. An important element you will find in this block is
+    <a href="peers.html">Peers</a> framework, that is one of the corner stones
+    of Turbine framework along with Services and Modules. Peers allow you to
+    create relationship between tables in a relational database and classes in
+    your application. It also allows to create queries in an Object-oriented way. </p>
+
+    <p><a href="project-map/object-services.html"><b>Object services</b></a></p>
+
+    <p> One of the greatest advantages of working in Java Servlets environment,
+    is the statefullness of your application. You can create object and hold
+    them in memory, to avoid repeated loading information form external
+    sources, like disk files or the database. Turbine provides a few
+    Services that will help you with management of these objects. One of them
+    is Pool service that allows you to create pools of reusable object that
+    may be acquired from the pool by a thread processing a request, and
+    recycled when no longer needed. Cache service will help you with
+    managing objects that contain information that can be reused multiple
+    times. </p>
+
+    <p><a href="project-map/auxilary-services.html"><b>Auxilary Services</b></a></p>
+
+    <p> In this section you will find other services that might be useful
+    in the building your application. For example
+    <a href="http://www.xmlrpc.com">XMLRPC</a> service that allows
+    communication between applications within a heterogenous environment
+    using XML-based protocol over HTTP. There are also services allowing
+    manipulation of XML content using XSLT, and a service that manages
+    creating contexts for performing JNDI operations. </p>
+
+    <p><a href="project-map/email.html"><b>E-mail messages</b></a></p>
+
+    <p> Turbine can help you with creating and sending e-mail. Also
+    with the help of templates, just as those you use for displaying
+    HTML pages. </p>
+
+    <p><a href="project-map/utility.html"><b>Utility classes</b></a></p>
+
+    <p> This block encompasses the various utility classes contained in
+    Turbine. You should check those classes, as they solve some common
+    problems encountered in web application making. </p>
+
+    <p><a href="project-map/tools.html"><b>Turbine tools</b></a></p>
+
+    <p> In this block, you will find tools that ship together with Turbine.
+    These tools are runnable from the command line, and are used for the
+    development purposes, not during the normal operation of an application.
+
+    The tools include <a href="howto/torque-howto.html">Torque</a>, the tool for
+    generating Peer Framework classes for your application,
+    <a href="services/intake-service.html">Intake</a> that generates classes for automation
+    of processing of complex HTML forms. <!--, and the <a href="migrator.html">
+    Migrator</a>, the tool that helps you with bringing your application
+    up to date with newer releases of Turbine, by performing batches
+    of search-and-replace operations on your sources. When used properly,
+    it can save you a plenty of typing.--> </p>
+
+    </section>
+
+    <section name="Updating project map">
+
+    <p> This section is meant for Turbine developers. </p>
+
+    <p> Whenever you want to work on bringing the project map up to date, you
+    should run the <code>update-classlist.sh</code> script contained in the
+    <code>xdocs/project-map</code> directory. It will bring the <code>classlist</code>
+    file, also in  that directory in sync with the Turbine source files.
+    It will also create a  cvs diff of the <code>classlist</code> file and save the
+    result into <code>changes</code> file. Open it and see the changes in the
+    codebase between the last time the project map was updated, and the present.
+    When you commit the modified xdocs, don't  forget to commit <code>classlist</code>
+    file as well! </p>
+
+    </section>
+
+    </body>
+
+</document>
diff --git a/src/site/xdoc/proposals.xml b/src/site/xdoc/proposals.xml
new file mode 100644
index 00000000..90c60811
--- /dev/null
+++ b/src/site/xdoc/proposals.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+
+<document>
+
+ <properties>
+  <title>Turbine Services</title>
+ </properties>
+
+<body>
+
+<section name="Proposals">
+
+<p>
+These are the proposals that are up on the table:
+</p>
+
+<ul>
+<li><a href="proposals/application-service.html">Application Service</a></li>
+<li><a href="proposals/browser-bound-app-context.html">Browser Bound Application Context</a></li>
+<li><a href="proposals/i18n.html">i18n</a></li>
+<li><a href="proposals/naming-service.html">Naming Service</a></li>
+<li><a href="proposals/pp.html">PP and Related Classes</a></li>
+<li><a href="proposals/reusable-components.html">Reusable Components</a></li>
+<li><a href="proposals/security-service.html">Security Service</a></li>
+<li><a href="proposals/services-repository.html">Services Repository</a></li>
+<li><a href="proposals/unified-templating.html">Unified Templating Service</a></li>
+</ul>
+
+</section>
+
+</body>
+</document>
diff --git a/src/site/xdoc/proposals/application-service.xml b/src/site/xdoc/proposals/application-service.xml
new file mode 100644
index 00000000..02936076
--- /dev/null
+++ b/src/site/xdoc/proposals/application-service.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0"?>
+<!-- 
+/*
+ * 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.
+ */
+ -->
+
+<document>
+
+  <properties>
+    <title>Application Service Proposal</title>
+  </properties>
+
+<body>
+
+<section name="Description">
+  <p>
+    The application services would allow fully functional Turbine applications
+    to be packaged up in the form of JAR files and deployed during Turbine
+    startup.
+  </p>
+</section>
+
+<section name="Rationale">
+<p>
+</p>
+</section>
+
+<section name="Requirements">
+<ul>
+  <li>
+    Turbine would probably process a directory of JAR files
+    that contain sub-applications. The manifest would contain
+    a set of instructions to be used by the application service
+    so that the sub-application would be processed correctly
+    and usable by Turbine. This may be the module.packages
+    to add, or template paths to add, or whatever else is
+    needed to bootstrap the sub-application.
+  </li>
+
+  <li>
+    Module packages have to be dynamically configurable.
+    The assembler broker must accept additional packages
+    to look in for modules after the system has started.
+  </li>
+  
+  <li>
+    Must be able to load templates from JAR files. Velocity
+    can do this, and it can probably be done for the other
+    template services as well.
+  </li>
+
+  <li>
+    Configuration information must be able to enter a
+    running Turbine application. A sub application might
+    have many forms of configuration info. It might be properties
+    that have to be accessible via TurbineResources. Or
+    it might configuration information to be used by one
+    of the services, say for example an intake XML descriptor
+    for the input forms used in the sub-application.
+    <p/>
+    The services in general might need some work to allow
+    dynamic configuration so that sub-applications can
+    really work properly.
+  </li>
+  
+  <li>
+    Sub-applications may require certain operations to be
+    executed in order to run. This might be a forum application
+    that has an SQL schema that needs to be inserted in order
+    to function. These stops could either be performed by Ant,
+    or scripts that could be executed by the proposed BSF
+    (Bean Scripting Framework) service.
+  </li>
+
+  <li>
+    Sub-applications will require a unique id to to keep things
+    like templates in their own namespace. Eventually there
+    may also be other entities that need to be kept separate.
+    We could probably start a catalog of sub-applications to
+    make sure that people don't use a unique id already being
+    used by another sub-application in existence.
+  </li>
+
+  <li>
+    Extension do DynamicURI and derivates to support new parameter
+    (sub-application selector)
+  </li>
+</ul>
+</section>
+
+
+<section name="Scope">
+<p>
+</p>
+</section>
+
+<section name="Initial Source">
+<p>
+</p>
+</section>
+
+<section name="Initial Committers">
+<p>
+</p>
+</section>
+
+</body>
+</document>
diff --git a/src/site/xdoc/proposals/browser-bound-app-context.xml b/src/site/xdoc/proposals/browser-bound-app-context.xml
new file mode 100644
index 00000000..6981cadb
--- /dev/null
+++ b/src/site/xdoc/proposals/browser-bound-app-context.xml
@@ -0,0 +1,167 @@
+<?xml version="1.0"?>
+<!-- 
+/*
+ * 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.
+ */
+ -->
+
+<document>
+
+  <properties>
+    <title>Application Service Proposal</title>
+  </properties>
+
+<body>
+
+<section name="Browser window bound application context">
+
+<p><b>The problem: multiple windows</b></p>
+<p>
+Suppose that you write an application that will have the ability to open 
+multiple windows at once. These windows will contain views for different 
+application modules. Sometimes, different windows will show the same module, 
+but the data or it's presentation form will be different. It is obvious that 
+each of the windows has an amount of state information associated with it. The 
+HTTP protocol is by design stateless. Because statefullness is necessary for a 
+multitude of applications, cookies mechanism was introduced. Usually, the 
+cookies passed between the server and browser carry only an identifier of the 
+session. The actual data is kept in the servers memory (or other storage device) 
+Unfortunately cookies are not appropriate for managing state information 
+associated with a single window. The primary way of overcoming this limitation 
+is encoding information about the subset of data to be displayed and the 
+presentation details (like sorting order) into the request URLs. This technique 
+allows the user to maintain multiple simultaneous sessions with the same screen 
+of the application in different browser windows, viewing different data sets or 
+using different presentation settings. This technique might be unacceptable in 
+two situations:
+</p>
+<ul>
+<li>the presentation settings should not be visible in the URL so that the user 
+can not tamper with them. </li>
+<li> the amount of state information is large and/or the generated page contains 
+large number of links. This would lead to generating large amounts of markup, 
+decreasing application responsiveness and consuming resources.</li>
+</ul>
+
+<p><b>The solution: server side window context</b></p>
+<p>
+A technique similar to that applied to global session data. Window specific 
+information can be stored on the server, and an token allowing to uniquely 
+identify this information can be added to all URLs generated on the page. 
+This way on the next request originating from a given browser window, the 
+application has access to the state information associated with this window.
+</p>
+
+<p><b>The problem: "Open in new window"</b></p>
+<p>
+If opening of windows in a multi-windowed application is utterly under control 
+of the application (the window is created using JavaScript, with context 
+identifier token removed from the URL, to inform the application that it needs 
+to create a new context) window contexts will work fine. In reality users will 
+often create new windows using "open in new window" command, or by dragging 
+URLs between windows. In each of the situations mentioned above, multiple 
+windows displaying the same URL (and thus, by definition the same collection 
+of cookies will appear. These windows are indistinguishable to the application, 
+but it is undesirable that these windows share the window context. That would 
+mean that changes to the state information performed in one window would affect 
+all future requests to the other windows in the group.
+</p>
+
+<p><b>The solution: session context tree</b></p>
+<p>
+To effectively detect opening of windows, the token identifying a session 
+context must be different for every request. Please recall the example of a few
+windows opened "open in new window" command. All of them share the URL, and the 
+context identifying token contained in it. This means that they can access the 
+state information that was valid during the previous request. The data subset 
+displayed and the presentation settings used in all of the windows is the same. 
+But because there are multiple windows now, the session context must split. New 
+contexts must be created, inheriting the contents of the parent (previous) 
+context, an tokens identifying these newly generated context must be included 
+in all URLs generated on the associated pages.
+</p>
+
+
+<p><b>The problem: the "back" button</b></p>
+<p>
+While reading the previous paragraph, you may have an impression that it is 
+possible to perform educated guesses about context branching points and store 
+only as many contexts as there are windows simultaneously open. But when you 
+consider the situation when user uses "back" and "forward" buttons to navigate 
+the application, you'll find out that ALL of the contexts must be remembered 
+by the server. The state information associated with each request may be used 
+multiple times in the future. An LRU garbage collection scheme could be 
+performed on the context objects (only a fixed number of most recently accessed
+context would be remembered) to conserve server's memory. Unfortunately, this 
+could easily lead to undesirable application operation. Imagine an application 
+with two windows open.  An user performs an operation in the window A, then 
+switches to window B an performs so many operations in it that the context of 
+the window A is discarded. Then, performing an operation in the window A may 
+yield unexpected results because the state information was lost.
+</p>
+
+<p><b>Explicit vs Implicit cloning.</b></p>
+
+<p>
+All of the the session contexts have to be replicated per every hit to the
+application. Memory consumption seems like an important factor to consider
+here. I had an idea of reducing it a bit, by requiring the programmer to 
+explicitly copy the data from the previous context to the current context
+that are important. This is makes using session contexts tedious, but 
+avoids cloning unused data over and over, when the user moves from one
+screen to another (which will obviously need different state information).
+This has the following downside - when the user uses a link to go back
+to a screen that he visited earlier, the state information will be lost,
+because the other screen didn't clone it (because it had no idea about them). 
+The presentation details will be reset to normal. On the other hand, if 
+the user pressed the "back" button multiple times to go back to that screen, 
+the presentation details would be remembered (the URLs contain valid
+context identifier tokens). The conclusion is, that cloning all of the 
+stuff contained in the context gives a better user experience. Memory is
+cheap these days, right? Oh, don't worry that those context have to stay
+in memory forever. They should be bound to a global (cookie style) session
+and discarded when the global session times out.
+</p>
+
+<p><b>A sketch of implementation</b></p>
+
+<p>
+<ul>
+    <li>
+        SessionContext interface similar to that of ServletSession
+    </li>
+    <li>
+        getGlobalContext() and getLocalContext() methods in RunData
+    </li> 
+    <li>
+        a wrapper object containing a global context and multiple
+        local context keyed by id, to be stored in the HTTP session 
+    </li>
+    <li>
+        context id tokens automatically picked up (after ParameterParser 
+        runs) and the context extracted/cloned/created as needed using
+        the wrapper object from the session, and appropriate contexts
+        made available through RunData
+    </li>
+    <li>
+        context id added to the url by the DynamicURI et al
+    </li>
+</ul>
+</p>
+
+</section>
+
+</body>
+</document>
diff --git a/src/site/xdoc/proposals/i18n.xml b/src/site/xdoc/proposals/i18n.xml
new file mode 100644
index 00000000..91e1291c
--- /dev/null
+++ b/src/site/xdoc/proposals/i18n.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0"?>
+<!-- 
+/*
+ * 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.
+ */
+ -->
+
+<document>
+
+  <properties>
+    <title>Application Service Proposal</title>
+  </properties>
+
+<body>
+
+<section name="i18n">
+<ul>
+  <li>
+    Messages that turbine outputs should live in a resource bundles, not
+    in in TR.props
+  </li>
+  <li>
+    Template lookups depending on locale (Is Ilkka working on that?) 
+  </li>
+</ul>
+
+</section>
+
+
+</body>
+</document>
diff --git a/src/site/xdoc/proposals/naming-service.xml b/src/site/xdoc/proposals/naming-service.xml
new file mode 100644
index 00000000..0024c83f
--- /dev/null
+++ b/src/site/xdoc/proposals/naming-service.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0"?>
+<!-- 
+/*
+ * 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.
+ */
+ -->
+
+<document>
+
+  <properties>
+    <title>Application Service Proposal</title>
+  </properties>
+
+<body>
+
+<section name="Naming service">
+<ul>
+  <li>
+    this service is rater outdated, it needs some cleanup, and adding
+    suppport for DirContexts (low priority, might be useful in  
+    creating LDAP User Manager / Security Service implementations)
+  </li>
+</ul>
+
+</section>
+
+
+</body>
+</document>
diff --git a/src/site/xdoc/proposals/pp.xml b/src/site/xdoc/proposals/pp.xml
new file mode 100644
index 00000000..ff4420a3
--- /dev/null
+++ b/src/site/xdoc/proposals/pp.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0"?>
+<!-- 
+/*
+ * 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.
+ */
+ -->
+
+<document>
+
+  <properties>
+    <title>Application Service Proposal</title>
+  </properties>
+
+<body>
+
+<section name="Parameter parser and its ilk">
+
+<ul>
+  <li>
+    clean up and orthogonalize APIs (add vs append vs set)
+  </li>
+
+  <li>
+    what the heck is uploadData? I think UploadService/FileItems do the
+    trick just fine
+  </li>
+
+  <li>
+    BaseValueParser should not extend RecyclableSupport. If I understand
+    the pattern correctly, it should include an instance of
+    RecyclableSupport and delegate Recyclable interface method to it. 
+    The same goes for TurbineDefaultRunData. To prevent people from doing 
+    that RecyclableSupport should not implement Recyclable itself. AFAIK, this 
+    kind of apprach is used to emulate multiple inheritance in Java. 
+    I'd appreciate a comment on this issue from Ilkka.
+  </li>
+</ul>
+
+</section>
+
+</body>
+</document>
diff --git a/src/site/xdoc/proposals/resources-service.xml b/src/site/xdoc/proposals/resources-service.xml
new file mode 100644
index 00000000..8ca6d18b
--- /dev/null
+++ b/src/site/xdoc/proposals/resources-service.xml
@@ -0,0 +1,54 @@
+<?xml version="1.0"?>
+<!-- 
+/*
+ * 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.
+ */
+ -->
+
+<document>
+
+  <properties>
+    <title>Application Service Proposal</title>
+  </properties>
+
+<body>
+
+<section name="Resource Service">
+
+<p>
+  <li>
+    clean up property names so that dot is used as namespace separator,
+    not as a space character replacement examples:
+    <br/>
+    services.GlobalCacheService.cache.check.frequecy should be:
+    <br/>
+    services.GlobalCacheService.cachCheckFrequency
+    <br/>
+    services.PullService.tools.per.request.refresh should be:
+    <br/>
+    services.PullService.toolsPerRequestRefresh
+    <p/>
+
+    if we do the above, it would be easy to map the dot separated property
+    names onto a DOM tree or a JNDI namespace. These two alternative
+    ResourceService implementation would be a nice addition to Turbine.
+  </li>
+</p>
+
+</section>
+
+
+</body>
+</document>
diff --git a/src/site/xdoc/proposals/reusable-components.xml b/src/site/xdoc/proposals/reusable-components.xml
new file mode 100644
index 00000000..75d97cee
--- /dev/null
... 4912 lines suppressed ...