diff --git a/Java-base/maven-war-plugin/Dockerfile b/Java-base/maven-war-plugin/Dockerfile
new file mode 100644
index 000000000..e208c4890
--- /dev/null
+++ b/Java-base/maven-war-plugin/Dockerfile
@@ -0,0 +1,28 @@
+FROM ubuntu:22.04
+
+RUN export DEBIAN_FRONTEND=noninteractive \
+    && apt-get update \
+    && apt-get install -y software-properties-common \
+    && add-apt-repository ppa:deadsnakes/ppa \
+    && apt-get update \
+    && apt-get install -y \
+        build-essential \
+        git \
+        vim \
+        jq \
+    && apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/list/*
+
+RUN apt-get -y install sudo \
+      openjdk-8-jdk \
+      maven
+
+RUN bash -c "echo 2 | update-alternatives --config java"
+
+COPY src /workspace
+WORKDIR /workspace
+
+RUN mvn install -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false
+
+RUN mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100
+
+ENV TZ=Asia/Seoul
diff --git a/Java-base/maven-war-plugin/src/Jenkinsfile b/Java-base/maven-war-plugin/src/Jenkinsfile
new file mode 100644
index 000000000..e9f05f7d9
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/Jenkinsfile
@@ -0,0 +1,20 @@
+/**
+ * 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.
+ */
+
+asfMavenTlpPlgnBuild()
diff --git a/Java-base/maven-war-plugin/src/README.md b/Java-base/maven-war-plugin/src/README.md
new file mode 100644
index 000000000..19bf10233
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/README.md
@@ -0,0 +1,99 @@
+<!---
+ 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.
+-->
+Contributing to [Apache Maven WAR Plugin](https://maven.apache.org/plugins/maven-war-plugin/)
+======================
+
+[![ASF Jira](https://img.shields.io/endpoint?url=https%3A%2F%2Fmaven.apache.org%2Fbadges%2Fasf_jira-MWAR.json)][jira]
+[![Apache License, Version 2.0, January 2004](https://img.shields.io/github/license/apache/maven.svg?label=License)][license]
+[![Maven Central](https://img.shields.io/maven-central/v/org.apache.maven.plugins/maven-war-plugin.svg?label=Maven%20Central)](https://search.maven.org/artifact/org.apache.maven.plugins/maven-war-plugin)
+[![Jenkins Status](https://img.shields.io/jenkins/s/https/builds.apache.org/job/maven-box/job/maven-war-plugin/job/master.svg?)][build]
+[![Jenkins tests](https://img.shields.io/jenkins/t/https/builds.apache.org/job/maven-box/job/maven-war-plugin/job/master.svg?)][test-results]
+
+
+You have found a bug or you have an idea for a cool new feature? Contributing
+code is a great way to give something back to the open source community. Before
+you dig right into the code, there are a few guidelines that we need
+contributors to follow so that we can have a chance of keeping on top of
+things.
+
+Getting Started
+---------------
+
++ Make sure you have a [JIRA account](https://issues.apache.org/jira/).
++ Make sure you have a [GitHub account](https://github.com/signup/free).
++ If you're planning to implement a new feature, it makes sense to discuss your changes 
+  on the [dev list][ml-list] first. 
+  This way you can make sure you're not wasting your time on something that isn't 
+  considered to be in Apache Maven's scope.
++ Submit a ticket for your issue, assuming one does not already exist.
+  + Clearly describe the issue, including steps to reproduce when it is a bug.
+  + Make sure you fill in the earliest version that you know has the issue.
++ Fork the repository on GitHub.
+
+Making and Submitting Changes
+--------------
+
+We accept Pull Requests via GitHub. The [developer mailing list][ml-list] is the
+main channel of communication for contributors.  
+There are some guidelines which will make applying PRs easier for us:
++ Create a topic branch from where you want to base your work (this is usually the master branch).
+  Push your changes to a topic branch in your fork of the repository.
++ Make commits of logical units.
++ Respect the original code style: by using the same [codestyle][code-style],
+  patches should only highlight the actual difference, not being disturbed by any formatting issues:
+  + Only use spaces for indentation.
+  + Create minimal diffs - disable on save actions like reformat source code or organize imports. 
+    If you feel the source code should be reformatted, create a separate PR for this change.
+  + Check for unnecessary whitespace with `git diff --check` before committing.
++ Make sure your commit messages are in the proper format. Your commit message should contain the key of the JIRA issue.
+```
+[MWAR-XXX] - Subject of the JIRA Ticket
+ Optional supplemental description.
+```
++ Make sure you have added the necessary tests (JUnit/IT) for your changes.
++ Run all the tests with `mvn -Prun-its verify` to assure nothing else was accidentally broken.
++ Submit a pull request to the repository in the Apache organization.
++ Update your JIRA ticket and include a link to the pull request in the ticket.
+
+If you plan to contribute on a regular basis, please consider filing a [contributor license agreement][cla].
+
+Making Trivial Changes
+----------------------
+
+For changes of a trivial nature to comments and documentation, it is not always
+necessary to create a new ticket in JIRA.  In this case, it is appropriate to
+start the first line of a commit with '(doc)' instead of a ticket number.
+
+Additional Resources
+--------------------
+
++ [Contributing patches](https://maven.apache.org/guides/development/guide-maven-development.html#Creating_and_submitting_a_patch)
++ [Apache Maven WAR JIRA project page][jira]
++ [Contributor License Agreement][cla]
++ [General GitHub documentation](https://help.github.com/)
++ [GitHub pull request documentation](https://help.github.com/send-pull-requests/)
++ [Apache Maven Twitter Account](https://twitter.com/ASFMavenProject)
++ #Maven IRC channel on freenode.org
+
+[jira]: https://issues.apache.org/jira/projects/MWAR/
+[license]: https://www.apache.org/licenses/LICENSE-2.0
+[ml-list]: https://maven.apache.org/mailing-lists.html
+[code-style]: https://maven.apache.org/developers/conventions/code.html
+[cla]: https://www.apache.org/licenses/#clas
+[maven-wiki]: https://cwiki.apache.org/confluence/display/MAVEN/Index
+[test-results]: https://builds.apache.org/job/maven-box/job/maven-war-plugin/job/master/lastCompletedBuild/testReport/
+[build]: https://builds.apache.org/job/maven-box/job/maven-war-plugin/job/master/
diff --git a/Java-base/maven-war-plugin/src/deploySite.sh b/Java-base/maven-war-plugin/src/deploySite.sh
new file mode 100755
index 000000000..f6c265d75
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/deploySite.sh
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+#
+# 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.
+#
+
+mvn -Preporting site site:stage $@
+mvn scm-publish:publish-scm $@
diff --git a/Java-base/maven-war-plugin/src/pom.xml b/Java-base/maven-war-plugin/src/pom.xml
new file mode 100644
index 000000000..7256fb4ac
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/pom.xml
@@ -0,0 +1,263 @@
+<?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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <artifactId>maven-plugins</artifactId>
+    <groupId>org.apache.maven.plugins</groupId>
+    <version>34</version>
+    <relativePath />
+  </parent>
+
+  <artifactId>maven-war-plugin</artifactId>
+  <version>3.3.1-SNAPSHOT</version>
+  <packaging>maven-plugin</packaging>
+
+  <name>Apache Maven WAR Plugin</name>
+  <description>Builds a Web Application Archive (WAR) file from the project output and its dependencies.</description>
+
+  <prerequisites>
+    <maven>${mavenVersion}</maven>
+  </prerequisites>
+
+  <scm>
+    <connection>scm:git:https://gitbox.apache.org/repos/asf/maven-war-plugin.git</connection>
+    <developerConnection>scm:git:https://gitbox.apache.org/repos/asf/maven-war-plugin.git</developerConnection>
+    <url>https://github.com/apache/maven-war-plugin/tree/${project.scm.tag}</url>
+    <tag>HEAD</tag>
+  </scm>
+  <issueManagement>
+    <system>JIRA</system>
+    <url>https://issues.apache.org/jira/browse/MWAR</url>
+  </issueManagement>
+  <ciManagement>
+    <system>Jenkins</system>
+    <url>https://builds.apache.org/job/maven-box/job/maven-war-plugin/</url>
+  </ciManagement>
+  <distributionManagement>
+    <site>
+      <id>apache.website</id>
+      <url>scm:svn:https://svn.apache.org/repos/asf/maven/website/components/${maven.site.path}</url>
+    </site>
+  </distributionManagement>
+
+  <properties>
+    <mavenArchiverVersion>3.5.0</mavenArchiverVersion>
+    <mavenFilteringVersion>3.1.1</mavenFilteringVersion>
+    <mavenVersion>3.0</mavenVersion>
+    <javaVersion>7</javaVersion>
+    <project.build.outputTimestamp>2020-06-06T06:50:15Z</project.build.outputTimestamp>
+  </properties>
+
+  <contributors>
+    <contributor>
+      <name>Auke Schrijnen</name>
+    </contributor>
+    <contributor>
+      <name>Ludwig Magnusson</name>
+    </contributor>
+    <contributor>
+      <name>Hayarobi Park</name>
+    </contributor>
+    <contributor>
+      <name>Enrico Olivelli</name>
+    </contributor>
+  </contributors>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-plugin-api</artifactId>
+      <version>${mavenVersion}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-core</artifactId>
+      <version>${mavenVersion}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-archiver</artifactId>
+      <version>${mavenArchiverVersion}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven.plugin-tools</groupId>
+      <artifactId>maven-plugin-annotations</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>commons-io</groupId>
+      <artifactId>commons-io</artifactId>
+      <version>2.6</version>
+    </dependency>
+    <dependency>
+      <groupId>org.codehaus.plexus</groupId>
+      <artifactId>plexus-archiver</artifactId>
+      <version>4.2.2</version>
+    </dependency>
+    <dependency>
+      <groupId>org.codehaus.plexus</groupId>
+      <artifactId>plexus-interpolation</artifactId>
+      <version>1.26</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.codehaus.plexus</groupId>
+      <artifactId>plexus-utils</artifactId>
+      <version>3.3.0</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.maven.shared</groupId>
+      <artifactId>maven-filtering</artifactId>
+      <version>${mavenFilteringVersion}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.maven.shared</groupId>
+      <artifactId>maven-mapping</artifactId>
+      <version>3.0.0</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-compat</artifactId>
+      <version>${mavenVersion}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.13</version>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.maven.plugin-testing</groupId>
+      <artifactId>maven-plugin-testing-harness</artifactId>
+      <version>2.1</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <resources>
+      <resource>
+        <directory>src/main/resources-filtered</directory>
+        <filtering>true</filtering>
+      </resource>
+    </resources>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-enforcer-plugin</artifactId>
+          <executions>
+            <execution>
+              <id>enforce-bytecode-version</id>
+              <goals>
+                <goal>enforce</goal>
+              </goals>
+              <configuration>
+                <rules>
+                  <enforceBytecodeVersion combine.children="append">
+                    <maxJdkVersion>${maven.compiler.target}</maxJdkVersion>
+                  </enforceBytecodeVersion>
+                </rules>
+                <fail>true</fail>
+              </configuration>
+            </execution>
+          </executions>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.rat</groupId>
+          <artifactId>apache-rat-plugin</artifactId>
+          <configuration>
+            <excludes combine.children="append">
+              <!--
+                ! No possibilities to add license information into a MANIFEST
+              -->
+              <exclude>src/it/MWAR-167/src/main/resources/MANIFEST.MF</exclude>
+            </excludes>
+          </configuration>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <configuration>
+          <systemPropertyVariables>
+            <project.build.directory>${project.build.directory}</project.build.directory>
+            <project.build.outputDirectory>${project.build.outputDirectory}</project.build.outputDirectory>
+          </systemPropertyVariables>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+  <profiles>
+    <profile>
+      <id>run-its</id>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-invoker-plugin</artifactId>
+            <configuration>
+              <goals>
+                <goal>clean</goal>
+                <goal>package</goal>
+              </goals>
+              <projectsDirectory>src/it</projectsDirectory>
+              <postBuildHookScript>verify</postBuildHookScript>
+              <preBuildHookScript>prebuild</preBuildHookScript>
+              <localRepositoryPath>${project.build.directory}/local-repo</localRepositoryPath>
+              <settingsFile>src/it/settings.xml</settingsFile>
+              <cloneProjectsTo>${project.build.directory}/it</cloneProjectsTo>
+            </configuration>
+            <executions>
+              <execution>
+                <id>install</id>
+                <phase>pre-integration-tests</phase>
+                <goals>
+                  <goal>install</goal>
+                </goals>
+                <configuration>
+                  <extraArtifacts>
+                    <extraArtifact>javax.servlet:servlet-api:2.4:jar</extraArtifact>
+                    <extraArtifact>javax.servlet:javax.servlet-api:3.0.1:jar</extraArtifact>
+                    <extraArtifact>org.apache.struts:struts-core:1.3.9:jar</extraArtifact>
+                    <extraArtifact>org.codehaus.plexus:plexus-utils:1.4.7:jar:sources</extraArtifact>
+                  </extraArtifacts>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
+
+</project>
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-128/pom.xml b/Java-base/maven-war-plugin/src/src/it/MWAR-128/pom.xml
new file mode 100644
index 000000000..cb2bfc482
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-128/pom.xml
@@ -0,0 +1,38 @@
+<?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.
+-->
+<project xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd' xmlns='http://maven.apache.org/POM/4.0.0'>
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>testwar</groupId>
+  <artifactId>MWAR-128</artifactId>
+  <packaging>war</packaging>
+  <version>1.0-SNAPSHOT</version>
+
+ <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-war-plugin</artifactId>
+        <version>@project.version@</version>
+        <configuration>
+          <includeEmptyDirectories>true</includeEmptyDirectories>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-128/prebuild.groovy b/Java-base/maven-war-plugin/src/src/it/MWAR-128/prebuild.groovy
new file mode 100644
index 000000000..f0f6e037d
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-128/prebuild.groovy
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+def dir = new File( basedir, "src/main/webapp/WEB-INF/logs" )
+dir.mkdirs()
+return true;
+
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-128/src/main/webapp/WEB-INF/web.xml b/Java-base/maven-war-plugin/src/src/it/MWAR-128/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 000000000..468ed7856
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-128/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,18 @@
+<!--
+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.
+-->
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-128/verify.groovy b/Java-base/maven-war-plugin/src/src/it/MWAR-128/verify.groovy
new file mode 100644
index 000000000..9a8843c2f
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-128/verify.groovy
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+
+def warFile = new java.util.jar.JarFile( new File( basedir, "target/MWAR-128-1.0-SNAPSHOT.war" ), false );
+assert warFile.getEntry( 'WEB-INF/logs' ) != null
+
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-129/invoker.properties b/Java-base/maven-war-plugin/src/src/it/MWAR-129/invoker.properties
new file mode 100644
index 000000000..7e6fbfd9f
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-129/invoker.properties
@@ -0,0 +1,18 @@
+# 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.
+
+invoker.goals=clean war:exploded
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-129/pom.xml b/Java-base/maven-war-plugin/src/src/it/MWAR-129/pom.xml
new file mode 100644
index 000000000..279a8489d
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-129/pom.xml
@@ -0,0 +1,121 @@
+<?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.
+-->
+<project xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd' xmlns='http://maven.apache.org/POM/4.0.0'>
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>testwar</groupId>
+  <artifactId>MWAR-129</artifactId>
+  <packaging>war</packaging>
+  <version>1.0-SNAPSHOT</version>
+  <name>MWAR-129 Maven Webapp</name>
+  <url>http://maven.apache.org</url>
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.1</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+ <build>
+    <defaultGoal>package</defaultGoal>
+    <resources>
+      <resource>
+        <filtering>true</filtering>
+        <directory>src/main/resources</directory>
+      </resource>
+      <resource>
+        <directory>src/main/java</directory>
+        <includes>
+          <include>**/*.xml</include>
+        </includes>
+      </resource>
+    </resources>
+    <testResources>
+      <testResource>
+        <directory>src/test/resources</directory>
+      </testResource>
+      <testResource>
+        <directory>src/main/webapp</directory>
+        <includes>
+          <include>**/*.xml</include>
+        </includes>
+      </testResource>
+      <testResource>
+        <directory>src/test/webapp</directory>
+        <includes>
+          <include>**/*.xml</include>
+        </includes>
+      </testResource>
+    </testResources>
+    <finalName>${project.artifactId}</finalName>
+    <plugins>
+      <plugin>
+        <artifactId>maven-war-plugin</artifactId>
+        <!--version>2.0.2</version-->
+        <!--version>2.1-alpha-2-SNAPSHOT</version-->
+        <version>@pom.version@</version>
+        <configuration>
+          <warSourceDirectory>src/main/webapp</warSourceDirectory>
+          <webResources>
+            <resource>
+              <filtering>true</filtering>
+              <directory>src/main/webapp</directory>
+              <targetPath>.</targetPath>
+              <includes>
+                <include>param.jsp</include>
+              </includes>
+            </resource>
+          </webResources>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <profiles>
+    <profile>
+      <id>profile1</id>
+      <activation>
+        <property>
+          <name>profile1</name>
+        </property>
+      </activation>
+      <build>
+        <finalName>profile1</finalName>
+      </build>
+      <properties>
+        <app.mainStyleSheet>profile1.css</app.mainStyleSheet>
+      </properties>
+    </profile>
+    <profile>
+      <id>profile2</id>
+      <activation>
+        <activeByDefault>true</activeByDefault>
+        <property>
+          <name>profile2</name>
+        </property>
+      </activation>
+      <build>
+        <finalName>profile2</finalName>
+      </build>
+      <properties>
+        <app.mainStyleSheet>profile2.css</app.mainStyleSheet>
+      </properties>
+    </profile>
+  </profiles>
+</project>
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-129/src/main/webapp/WEB-INF/web.xml b/Java-base/maven-war-plugin/src/src/it/MWAR-129/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 000000000..6a8fa709e
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-129/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,24 @@
+<!DOCTYPE web-app PUBLIC
+ "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+ "http://java.sun.com/dtd/web-app_2_3.dtd" >
+<!--
+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.
+-->
+<web-app>
+  <display-name>Archetype Created Web Application</display-name>
+</web-app>
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-129/src/main/webapp/index.jsp b/Java-base/maven-war-plugin/src/src/it/MWAR-129/src/main/webapp/index.jsp
new file mode 100755
index 000000000..9c9f33459
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-129/src/main/webapp/index.jsp
@@ -0,0 +1,23 @@
+<!--
+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.
+-->
+<html>
+<body>
+<h2>Hello World!</h2>
+</body>
+</html>
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-129/src/main/webapp/param.jsp b/Java-base/maven-war-plugin/src/src/it/MWAR-129/src/main/webapp/param.jsp
new file mode 100755
index 000000000..6be3a1be0
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-129/src/main/webapp/param.jsp
@@ -0,0 +1,27 @@
+<!--
+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.
+-->
+<c:set var="app_version" value="${pom.version}"/>
+<c:set var="app_mainStyleSheet" value="${app.mainStyleSheet}"/>
+
+<c:if test="${app_version}">
+  <c:set var="app_version" value="X.X.X.X"/>
+</c:if>
+<c:if test="${app_mainStyleSheet}">
+  <c:set var="app_mainStyleSheet" value="app_global.css"/>
+</c:if>
\ No newline at end of file
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-129/verify.bsh b/Java-base/maven-war-plugin/src/src/it/MWAR-129/verify.bsh
new file mode 100644
index 000000000..7b85cd782
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-129/verify.bsh
@@ -0,0 +1,66 @@
+
+/*
+ * 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.
+ */
+
+import java.io.*;
+import org.codehaus.plexus.util.*;
+
+boolean result = true;
+
+try
+{
+    File target = new File( basedir, "target" );
+    if ( !target.exists() || !target.isDirectory() )
+    {
+        System.err.println( "target file is missing or not a directory." );
+        return false;
+    }
+
+    File webappDirectory = new File( target, "profile2" );
+    if ( !webappDirectory.exists() || !webappDirectory.isDirectory() )
+    {
+        System.err.println( "webappDirectory is missing or not a directory." );
+        return false;
+    }
+
+    File param = new File( webappDirectory, "param.jsp" );
+    if ( !param.exists() || param.isDirectory() )
+    {
+        System.err.println( "param.jsp file is missing or a directory." );
+        return false;
+    }
+    System.out.println( " before reading param " );
+    String paramContent = FileUtils.fileRead( param );
+
+
+    int indexOf = paramContent.indexOf( "<c:set var=\"app_version\" value=\"1.0-SNAPSHOT\"/>" );
+    if ( indexOf < 0 )
+    {
+        System.err.println( "param.jsp not contains <c:set var=\"app_version\" value=\"1.0-SNAPSHOT\"/>" );
+        return false;
+    }
+
+}
+catch( Throwable e )
+{
+    e.printStackTrace();
+    result = false;
+}
+
+return result;
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-131/invoker.properties b/Java-base/maven-war-plugin/src/src/it/MWAR-131/invoker.properties
new file mode 100644
index 000000000..f93d074f8
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-131/invoker.properties
@@ -0,0 +1,19 @@
+# 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.
+
+invoker.goals=clean install
+invoker.maven.version=2.0.9+
\ No newline at end of file
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-131/mwar131-test/pom.xml b/Java-base/maven-war-plugin/src/src/it/MWAR-131/mwar131-test/pom.xml
new file mode 100644
index 000000000..b1b1d0559
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-131/mwar131-test/pom.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.
+-->
+<project>
+  <parent>
+    <artifactId>mwar131</artifactId>
+    <groupId>com.example</groupId>
+    <version>1.0-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+    <artifactId>mwar131-test</artifactId>
+  <name>Maven Quick Start Archetype</name>
+
+  <description>
+    Example project that expects the attached jar from mwar131-webapp to be on the compile and test classpath.
+  </description>
+
+  <version>1.0-SNAPSHOT</version>
+  <url>http://maven.apache.org</url>
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.1</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.example</groupId>
+      <artifactId>mwar131-webapp</artifactId>
+      <version>1.0-SNAPSHOT</version>
+      <classifier>classes</classifier>
+    </dependency>
+  </dependencies>
+</project>
\ No newline at end of file
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-131/mwar131-test/src/main/java/com/example/App.java b/Java-base/maven-war-plugin/src/src/it/MWAR-131/mwar131-test/src/main/java/com/example/App.java
new file mode 100644
index 000000000..d5290dfd6
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-131/mwar131-test/src/main/java/com/example/App.java
@@ -0,0 +1,32 @@
+package com.example;
+
+/*
+ * 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.
+ */
+
+/**
+ * Hello world!
+ *
+ */
+public class App 
+{
+    public static void main( String[] args )
+    {
+        System.out.println( "Hello World is " + Util.isPresent() );
+    }
+}
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-131/mwar131-test/src/test/java/com/example/AppTest.java b/Java-base/maven-war-plugin/src/src/it/MWAR-131/mwar131-test/src/test/java/com/example/AppTest.java
new file mode 100644
index 000000000..0c3fbb1cd
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-131/mwar131-test/src/test/java/com/example/AppTest.java
@@ -0,0 +1,62 @@
+package com.example;
+
+/*
+ * 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.
+ */
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Unit test for simple App.
+ */
+public class AppTest 
+    extends TestCase
+{
+    /**
+     * Create the test case
+     *
+     * @param testName name of the test case
+     */
+    public AppTest( String testName )
+    {
+        super( testName );
+    }
+
+    /**
+     * @return the suite of tests being tested
+     */
+    public static Test suite()
+    {
+        return new TestSuite( AppTest.class );
+    }
+
+    /**
+     * Rigourous Test :-)
+     */
+    public void testApp()
+    {
+        assertTrue( true );
+    }
+
+    public void testUtil()
+    {
+        assertTrue( Util.isPresent() );
+    }
+}
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-131/mwar131-webapp/pom.xml b/Java-base/maven-war-plugin/src/src/it/MWAR-131/mwar131-webapp/pom.xml
new file mode 100644
index 000000000..ee5ac62f5
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-131/mwar131-webapp/pom.xml
@@ -0,0 +1,59 @@
+<!--
+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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>com.example</groupId>
+    <artifactId>mwar131</artifactId>
+    <version>1.0-SNAPSHOT</version>
+  </parent>
+  <artifactId>mwar131-webapp</artifactId>
+  <packaging>war</packaging>
+  <name>MWAR-131 Webapp</name>
+
+  <description>Web application with classes that get installed as an
+  attached artifact with a classifier (mwar131-webapp-1.0-SNAPSHOT-classes.jar)</description>
+
+  <url>http://maven.apache.org</url>
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.1</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+        <groupId>org.apache.struts</groupId>
+        <artifactId>struts-core</artifactId>
+        <version>1.3.9</version>
+    </dependency>
+  </dependencies>
+  <build>
+    <finalName>mwar131-webapp</finalName>
+    <plugins>
+      <plugin>
+        <artifactId>maven-war-plugin</artifactId>
+        <configuration>
+          <attachClasses>true</attachClasses>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-131/mwar131-webapp/src/main/java/com/example/Util.java b/Java-base/maven-war-plugin/src/src/it/MWAR-131/mwar131-webapp/src/main/java/com/example/Util.java
new file mode 100644
index 000000000..b97118786
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-131/mwar131-webapp/src/main/java/com/example/Util.java
@@ -0,0 +1,28 @@
+package com.example;
+
+/*
+ * 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.
+ */
+
+public class Util
+{
+    public static boolean isPresent()
+    {
+        return true;
+    }
+}
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-131/mwar131-webapp/src/main/webapp/WEB-INF/web.xml b/Java-base/maven-war-plugin/src/src/it/MWAR-131/mwar131-webapp/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 000000000..ef9d13e76
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-131/mwar131-webapp/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,25 @@
+<!--
+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.
+-->
+<!DOCTYPE web-app PUBLIC
+ "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+ "http://java.sun.com/dtd/web-app_2_3.dtd" >
+
+<web-app>
+  <display-name>Archetype Created Web Application</display-name>
+</web-app>
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-131/mwar131-webapp/src/main/webapp/index.jsp b/Java-base/maven-war-plugin/src/src/it/MWAR-131/mwar131-webapp/src/main/webapp/index.jsp
new file mode 100644
index 000000000..9c9f33459
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-131/mwar131-webapp/src/main/webapp/index.jsp
@@ -0,0 +1,23 @@
+<!--
+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.
+-->
+<html>
+<body>
+<h2>Hello World!</h2>
+</body>
+</html>
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-131/mwar131-webapp2/pom.xml b/Java-base/maven-war-plugin/src/src/it/MWAR-131/mwar131-webapp2/pom.xml
new file mode 100644
index 000000000..0125a0bd2
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-131/mwar131-webapp2/pom.xml
@@ -0,0 +1,55 @@
+<?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.
+-->
+<project>
+  <parent>
+    <artifactId>mwar131</artifactId>
+    <groupId>com.example</groupId>
+    <version>1.0-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+    <artifactId>mwar131-webapp2</artifactId>
+  <packaging>war</packaging>
+  <name>Maven Webapp Archetype</name>
+
+  <description>
+    Webapp that declares the attached jar from mwar131-webapp as a dependency, which should show up in WEB-INF/lib
+    along with its transitive dependencies.
+  </description>
+
+  <version>1.0-SNAPSHOT</version>
+  <url>http://maven.apache.org</url>
+  <build>
+    <finalName>${project.artifactId}</finalName>
+  </build>
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.1</version>
+      <scope>test</scope>
+    </dependency>
+      <dependency>
+        <groupId>com.example</groupId>
+        <artifactId>mwar131-webapp</artifactId>
+        <version>1.0-SNAPSHOT</version>
+        <classifier>classes</classifier>
+      </dependency>
+  </dependencies>
+</project>
\ No newline at end of file
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-131/mwar131-webapp2/src/main/webapp/WEB-INF/web.xml b/Java-base/maven-war-plugin/src/src/it/MWAR-131/mwar131-webapp2/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 000000000..ef9d13e76
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-131/mwar131-webapp2/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,25 @@
+<!--
+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.
+-->
+<!DOCTYPE web-app PUBLIC
+ "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+ "http://java.sun.com/dtd/web-app_2_3.dtd" >
+
+<web-app>
+  <display-name>Archetype Created Web Application</display-name>
+</web-app>
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-131/mwar131-webapp2/src/main/webapp/index.jsp b/Java-base/maven-war-plugin/src/src/it/MWAR-131/mwar131-webapp2/src/main/webapp/index.jsp
new file mode 100644
index 000000000..9c9f33459
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-131/mwar131-webapp2/src/main/webapp/index.jsp
@@ -0,0 +1,23 @@
+<!--
+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.
+-->
+<html>
+<body>
+<h2>Hello World!</h2>
+</body>
+</html>
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-131/pom.xml b/Java-base/maven-war-plugin/src/src/it/MWAR-131/pom.xml
new file mode 100644
index 000000000..cc2bbca4a
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-131/pom.xml
@@ -0,0 +1,41 @@
+<?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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>com.example</groupId>
+  <artifactId>mwar131</artifactId>
+  <packaging>pom</packaging>
+  <version>1.0-SNAPSHOT</version>
+  <name>MWAR-131 Integration Test</name>
+  <url>http://maven.apache.org</url>
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-war-plugin</artifactId>
+        <version>@pom.version@</version>
+      </plugin>
+    </plugins>
+  </build>
+  <modules>
+    <module>mwar131-webapp</module>
+    <module>mwar131-test</module>
+    <module>mwar131-webapp2</module>
+  </modules>
+</project>
\ No newline at end of file
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-131/verify.bsh b/Java-base/maven-war-plugin/src/src/it/MWAR-131/verify.bsh
new file mode 100644
index 000000000..ca9fe0a5d
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-131/verify.bsh
@@ -0,0 +1,77 @@
+
+/*
+ * 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.
+ */
+
+import java.io.*;
+import org.codehaus.plexus.util.*;
+
+boolean result = true;
+
+try
+{
+
+  // Make sure the -classes jar from the first webapp is installed into the local repo
+  File localRepoClassesJar = new File( basedir,
+      "../../../target/local-repo/com/example/mwar131-webapp/1.0-SNAPSHOT/mwar131-webapp-1.0-SNAPSHOT-classes.jar");
+
+  if ( !localRepoClassesJar.exists() || localRepoClassesJar.isDirectory() )
+  {
+      System.err.println( "The -classes jar file is missing or is a directory." );
+      return false;
+  }
+
+  // Make sure the -classes jar is included in WEB-INF/lib of the second webapp
+  File classesJar = new File( basedir,
+      "mwar131-webapp2/target/mwar131-webapp2/WEB-INF/lib/mwar131-webapp-1.0-SNAPSHOT-classes.jar");
+
+  if ( !classesJar.exists() || classesJar.isDirectory() )
+  {
+      System.err.println( "The -classes jar file is missing or is a directory." );
+      return false;
+  }
+
+  // Make sure dependencies of the -classes jar are included in WEB-INF/lib of the second webapp
+  File strutsJar = new File( basedir,
+      "mwar131-webapp2/target/mwar131-webapp2/WEB-INF/lib/struts-core-1.3.9.jar");
+
+  if ( !strutsJar.exists() || strutsJar.isDirectory() )
+  {
+      System.err.println( "The Struts 1.3.9 jar file is missing or is a directory." );
+      return false;
+  }
+
+  // Make sure transitive dependencies of the -classes jar are included in WEB-INF/lib of the second webapp
+  File digesterJar = new File( basedir,
+      "mwar131-webapp2/target/mwar131-webapp2/WEB-INF/lib/commons-digester-1.8.jar");
+
+  if ( !digesterJar.exists() || digesterJar.isDirectory() )
+  {
+      System.err.println( "The Commons Digester 1.8 jar file is missing or is a directory." );
+      return false;
+  }
+
+}
+catch( Throwable e )
+{
+    e.printStackTrace();
+    result = false;
+}
+
+return result;
+
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-133/invoker.properties b/Java-base/maven-war-plugin/src/src/it/MWAR-133/invoker.properties
new file mode 100644
index 000000000..7e6fbfd9f
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-133/invoker.properties
@@ -0,0 +1,18 @@
+# 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.
+
+invoker.goals=clean war:exploded
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-133/pom.xml b/Java-base/maven-war-plugin/src/src/it/MWAR-133/pom.xml
new file mode 100644
index 000000000..99248bc3b
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-133/pom.xml
@@ -0,0 +1,58 @@
+<?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.
+-->
+<project xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd' xmlns='http://maven.apache.org/POM/4.0.0'>
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>testwar</groupId>
+  <artifactId>MWAR-133</artifactId>
+  <packaging>war</packaging>
+  <version>1.0-SNAPSHOT</version>
+  <name>MWAR-133 Maven Webapp</name>
+  <description>MWAR-133 it</description>
+
+  <build>
+    <resources>
+      <resource>
+        <directory>src/main/resources</directory>
+        <filtering>true</filtering>
+      </resource>
+    </resources>
+    <plugins>
+      <plugin>
+        <artifactId>maven-war-plugin</artifactId>
+        <version>@pom.version@</version>
+        <configuration>
+          <webResources>
+            <resource>
+              <directory>src/main/webresources</directory>
+              <filtering>true</filtering>
+            </resource>
+          </webResources>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <dependencies>
+    <dependency>
+      <groupId>org.codehaus.plexus</groupId>
+      <artifactId>plexus-utils</artifactId>
+      <version>1.4.6</version>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-133/src/main/webapp/WEB-INF/web.xml b/Java-base/maven-war-plugin/src/src/it/MWAR-133/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 000000000..6a8fa709e
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-133/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,24 @@
+<!DOCTYPE web-app PUBLIC
+ "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+ "http://java.sun.com/dtd/web-app_2_3.dtd" >
+<!--
+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.
+-->
+<web-app>
+  <display-name>Archetype Created Web Application</display-name>
+</web-app>
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-133/src/main/webresources/filtered.properties b/Java-base/maven-war-plugin/src/src/it/MWAR-133/src/main/webresources/filtered.properties
new file mode 100644
index 000000000..d60a845f6
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-133/src/main/webresources/filtered.properties
@@ -0,0 +1,21 @@
+# 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.
+
+#
+# Not Replaced with the pom version
+#
+app.version=${node.version}
\ No newline at end of file
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-133/verify.bsh b/Java-base/maven-war-plugin/src/src/it/MWAR-133/verify.bsh
new file mode 100644
index 000000000..88989630b
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-133/verify.bsh
@@ -0,0 +1,66 @@
+
+/*
+ * 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.
+ */
+
+import java.io.*;
+import org.codehaus.plexus.util.*;
+
+boolean result = true;
+
+try
+{
+    File target = new File( basedir, "target" );
+    if ( !target.exists() || !target.isDirectory() )
+    {
+        System.err.println( "target file is missing or not a directory." );
+        return false;
+    }
+
+    File webappDirectory = new File( target, "MWAR-133-1.0-SNAPSHOT" );
+    if ( !webappDirectory.exists() || !webappDirectory.isDirectory() )
+    {
+        System.err.println( "webappDirectory is missing or not a directory." );
+        return false;
+    }
+
+    File filtered = new File( webappDirectory, "filtered.properties" );
+    if ( !filtered.exists() || filtered.isDirectory() )
+    {
+        System.err.println( "filtered.properties file is missing or a directory." );
+        return false;
+    }
+    System.out.println( " before reading filtered.properties" );
+    String paramContent = FileUtils.fileRead( filtered );
+
+
+    int indexOf = paramContent.indexOf( "app.version=${node.version}" );
+    if ( indexOf < 0 )
+    {
+        System.err.println( "filtered.properties was not filtered with the value of ${node.version}" );
+        return false;
+    }
+
+}
+catch( Throwable e )
+{
+    e.printStackTrace();
+    result = false;
+}
+
+return result;
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-139/pom.xml b/Java-base/maven-war-plugin/src/src/it/MWAR-139/pom.xml
new file mode 100644
index 000000000..a51346a8d
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-139/pom.xml
@@ -0,0 +1,48 @@
+<?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.
+-->
+<project xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
+         xsi:schemaLocation='http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd'
+         xmlns='http://maven.apache.org/POM/4.0.0'>
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>testwar</groupId>
+  <artifactId>MWAR-139</artifactId>
+  <packaging>war</packaging>
+  <version>1.0-SNAPSHOT</version>
+  <name>MWAR-139 Maven Webapp</name>
+  <url>http://maven.apache.org</url>
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-war-plugin</artifactId>
+        <version>@pom.version@</version>
+        <configuration>
+          <warSourceDirectory>src/main/webapp</warSourceDirectory>
+          <webResources>
+            <resource>
+              <directory>src/main/webresources</directory>
+              <filtering>true</filtering>
+            </resource>
+          </webResources>
+
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-139/src/main/webapp/WEB-INF/web.xml b/Java-base/maven-war-plugin/src/src/it/MWAR-139/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 000000000..6a8fa709e
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-139/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,24 @@
+<!DOCTYPE web-app PUBLIC
+ "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+ "http://java.sun.com/dtd/web-app_2_3.dtd" >
+<!--
+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.
+-->
+<web-app>
+  <display-name>Archetype Created Web Application</display-name>
+</web-app>
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-139/src/main/webresources/filterme.xml b/Java-base/maven-war-plugin/src/src/it/MWAR-139/src/main/webresources/filterme.xml
new file mode 100644
index 000000000..2365ca4c7
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-139/src/main/webresources/filterme.xml
@@ -0,0 +1,23 @@
+<!--
+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.
+-->
+<foo>
+  <text>${foo.url}</text>
+  <text>hallo @@ hallo</text>
+  <text2>start-${}-end</text2>
+</foo>
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-139/verify.bsh b/Java-base/maven-war-plugin/src/src/it/MWAR-139/verify.bsh
new file mode 100644
index 000000000..390c0be32
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-139/verify.bsh
@@ -0,0 +1,72 @@
+
+/*
+ * 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.
+ */
+
+import java.io.*;
+import org.codehaus.plexus.util.*;
+
+boolean result = true;
+
+try
+{
+    File target = new File( basedir, "target" );
+    if ( !target.exists() || !target.isDirectory() )
+    {
+        System.err.println( "target file is missing or not a directory." );
+        return false;
+    }
+
+    File webappDirectory = new File( target, "MWAR-139-1.0-SNAPSHOT" );
+    if ( !webappDirectory.exists() || !webappDirectory.isDirectory() )
+    {
+        System.err.println( "webappDirectory is missing or not a directory." );
+        return false;
+    }
+
+    File param = new File( webappDirectory, "filterme.xml" );
+    if ( !param.exists() || param.isDirectory() )
+    {
+        System.err.println( "filterme.xml file is missing or a directory." );
+        return false;
+    }
+
+    String paramContent = FileUtils.fileRead( param );
+
+    int indexOf = paramContent.indexOf( "<text>hallo @@ hallo</text>" );
+    if ( indexOf < 0 )
+    {
+        System.err.println( "filterme.xml does not contains <text>hallo @@ hallo</text>" );
+        return false;
+    }
+
+    indexOf = paramContent.indexOf( "<text2>start-${}-end</text2>" );
+    if ( indexOf < 0 )
+    {
+        System.err.println( "filterme.xml does not contains <text2>start-${}-end</text2>" );
+        return false;
+    }
+
+}
+catch( Throwable e )
+{
+    e.printStackTrace();
+    result = false;
+}
+
+return result;
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-143/invoker.properties b/Java-base/maven-war-plugin/src/src/it/MWAR-143/invoker.properties
new file mode 100644
index 000000000..3376b9e49
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-143/invoker.properties
@@ -0,0 +1,18 @@
+# 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.
+
+invoker.goals=clean install
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-143/pom.xml b/Java-base/maven-war-plugin/src/src/it/MWAR-143/pom.xml
new file mode 100644
index 000000000..c975e36d8
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-143/pom.xml
@@ -0,0 +1,58 @@
+<?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.
+-->
+<project xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
+         xsi:schemaLocation='http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd'
+         xmlns='http://maven.apache.org/POM/4.0.0'>
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>debug.war</groupId>
+  <artifactId>MWAR-143</artifactId>
+  <packaging>pom</packaging>
+  <version>1.0-SNAPSHOT</version>
+  <name>MWAR-143 Maven Webapp</name>
+  <url>http://maven.apache.org</url>
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <artifactId>maven-war-plugin</artifactId>
+          <version>@pom.version@</version>
+          <configuration>
+            <nonFilteredFileExtensions>
+              <nonFilteredFileExtension>jpg</nonFilteredFileExtension>
+            </nonFilteredFileExtensions>
+          </configuration>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+  </build>
+  <modules>
+    <module>war-common</module>
+    <module>war-filter-overlay</module>
+  </modules>
+  <dependencyManagement>
+    <dependencies>
+      <dependency>
+        <groupId>debug.war</groupId>
+        <artifactId>common-overlay</artifactId>
+        <version>1.0-SNAPSHOT</version>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+</project>
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-143/verify.bsh b/Java-base/maven-war-plugin/src/src/it/MWAR-143/verify.bsh
new file mode 100644
index 000000000..45ed59e2f
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-143/verify.bsh
@@ -0,0 +1,124 @@
+
+/*
+ * 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.
+ */
+
+import java.io.*;
+import org.codehaus.plexus.util.*;
+
+boolean result = true;
+
+filesAreIdentical( File expected, File current )
+    throws IOException
+{
+    if ( expected.length() != current.length() )
+    {
+        return false;
+    }
+    FileInputStream expectedIn = new FileInputStream( expected );
+    FileInputStream currentIn = new FileInputStream( current );
+    try
+    {
+        byte[] expectedBuffer = IOUtil.toByteArray( expectedIn );
+
+        byte[] currentBuffer = IOUtil.toByteArray( currentIn );
+        if ( expectedBuffer.length != currentBuffer.length )
+        {
+            return false;
+        }
+        for ( int i = 0,size = expectedBuffer.length; i<size; i++ )
+        {
+            if ( expectedBuffer[i] != currentBuffer[i] )
+            {
+                return false;
+            }
+        }
+    }
+    finally
+    {
+        expectedIn.close();
+        currentIn.close();
+    }
+    return true;
+}
+
+try
+{
+
+    File originalImg = new File( basedir, "war-common/src/main/images/duke-beer.jpg" );
+
+    File targetImg = new File( basedir, "war-common/target/common-overlay-1.0-SNAPSHOT/duke-beer.jpg" );
+
+    boolean identical = filesAreIdentical( originalImg, targetImg );
+
+    if ( !identical )
+    {
+        System.err.println( "filtered images are not identical in war-common." );
+        return false;
+    }
+
+    File target = new File( basedir, "war-filter-overlay/target" );
+    if ( !target.exists() || !target.isDirectory() )
+    {
+        System.err.println( "target file is missing or not a directory." );
+        return false;
+    }
+
+    File webappDirectory = new File( target, "custom-manifest-1.0-SNAPSHOT" );
+    if ( !webappDirectory.exists() || !webappDirectory.isDirectory() )
+    {
+        System.err.println( "webappDirectory is missing or not a directory." );
+        return false;
+    }
+
+    File param = new File( webappDirectory, "WEB-INF/classes/filter.properties" );
+    if ( !param.exists() || param.isDirectory() )
+    {
+        System.err.println( "filter.properties file is missing or a directory." );
+        return false;
+    }
+
+
+    String paramContent = FileUtils.fileRead( param );
+
+    int indexOf = paramContent.indexOf( "debug.test = hello world !" );
+    if ( indexOf < 0 )
+    {
+        System.err.println( "filter.properties does not contains debug.test = hello world !" );
+        return false;
+    }
+
+    targetImg = new File( basedir, "war-filter-overlay/target/custom-manifest-1.0-SNAPSHOT/duke-beer.jpg" );
+
+    boolean identical = filesAreIdentical( originalImg, targetImg );
+
+    if ( !identical )
+    {
+        System.err.println( "filtered images are not identical with overlay." );
+        return false;
+    }
+
+}
+catch( Throwable e )
+{
+    e.printStackTrace();
+    result = false;
+}
+
+return result;
+
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-143/war-common/pom.xml b/Java-base/maven-war-plugin/src/src/it/MWAR-143/war-common/pom.xml
new file mode 100644
index 000000000..d22fdfb32
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-143/war-common/pom.xml
@@ -0,0 +1,52 @@
+<?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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>debug.war</groupId>
+    <artifactId>MWAR-143</artifactId>
+    <version>1.0-SNAPSHOT</version>
+  </parent>
+  <artifactId>common-overlay</artifactId>
+  <packaging>war</packaging>
+  
+  <build>
+    <plugins>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-war-plugin</artifactId>
+          <configuration>
+            <archive>
+              <manifestEntries>
+                <Class-Path>properties</Class-Path>
+              </manifestEntries>
+            </archive>
+            <webResources>
+              <resource>
+                <directory>src/main/images</directory>
+                <filtering>true</filtering>
+              </resource>
+            </webResources>
+          </configuration>
+        </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-143/war-common/src/main/images/duke-beer.jpg b/Java-base/maven-war-plugin/src/src/it/MWAR-143/war-common/src/main/images/duke-beer.jpg
new file mode 100755
index 000000000..8b43aa065
Binary files /dev/null and b/Java-base/maven-war-plugin/src/src/it/MWAR-143/war-common/src/main/images/duke-beer.jpg differ
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-143/war-common/src/main/resources/filter.properties b/Java-base/maven-war-plugin/src/src/it/MWAR-143/war-common/src/main/resources/filter.properties
new file mode 100644
index 000000000..624f14f21
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-143/war-common/src/main/resources/filter.properties
@@ -0,0 +1,21 @@
+# 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.
+
+title.main=Prototype ${pom.name} 
+title.version=version ${pom.version}
+
+debug.test = ${my.filter.value}
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-143/war-common/src/main/webapp/WEB-INF/web.xml b/Java-base/maven-war-plugin/src/src/it/MWAR-143/war-common/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 000000000..357cf72ca
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-143/war-common/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+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.
+-->
+<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
+         version="2.4">
+
+</web-app>
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-143/war-filter-overlay/pom.xml b/Java-base/maven-war-plugin/src/src/it/MWAR-143/war-filter-overlay/pom.xml
new file mode 100644
index 000000000..062fb1b80
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-143/war-filter-overlay/pom.xml
@@ -0,0 +1,65 @@
+<?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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>debug.war</groupId>
+    <artifactId>MWAR-143</artifactId>
+    <version>1.0-SNAPSHOT</version>
+  </parent>  
+  <artifactId>custom-manifest</artifactId>
+  <packaging>war</packaging>
+
+  <dependencies> 
+    <!-- War Overlay -->
+    <dependency>
+      <groupId>debug.war</groupId>
+      <artifactId>common-overlay</artifactId>
+      <version>1.0-SNAPSHOT</version>
+      <type>war</type>
+      <scope>runtime</scope>
+    </dependency>
+  </dependencies> 
+  
+  <build>
+    <plugins>      
+      <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-war-plugin</artifactId>
+          <configuration>
+            <overlays>
+              <overlay>
+                <groupId>debug.war</groupId>
+                <artifactId>common-overlay</artifactId>
+                <!--targetPath>filter</targetPath-->
+                <filtered>true</filtered>
+              </overlay>
+            </overlays>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  
+  <properties>
+     <my.filter.value>hello world !</my.filter.value>
+  </properties>
+  
+</project>
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-143/war-filter-overlay/src/main/webapp/WEB-INF/web.xml b/Java-base/maven-war-plugin/src/src/it/MWAR-143/war-filter-overlay/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 000000000..fc6e240ce
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-143/war-filter-overlay/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+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.
+-->
+<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
+         version="2.4">
+
+
+</web-app>
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-167/invoker.properties b/Java-base/maven-war-plugin/src/src/it/MWAR-167/invoker.properties
new file mode 100644
index 000000000..7e6fbfd9f
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-167/invoker.properties
@@ -0,0 +1,18 @@
+# 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.
+
+invoker.goals=clean war:exploded
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-167/pom.xml b/Java-base/maven-war-plugin/src/src/it/MWAR-167/pom.xml
new file mode 100644
index 000000000..174386f45
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-167/pom.xml
@@ -0,0 +1,49 @@
+<?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.
+-->
+<project xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd' xmlns='http://maven.apache.org/POM/4.0.0'>
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>testwar</groupId>
+  <artifactId>MWAR-167</artifactId>
+  <packaging>war</packaging>
+  <version>1.0-SNAPSHOT</version>
+  <name>MWAR-167 Maven Webapp</name>
+  <url>http://maven.apache.org</url>
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.1</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+ <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-war-plugin</artifactId>
+        <version>@project.version@</version>
+        <configuration>
+          <archive>
+	         <manifestFile>src/main/resources/MANIFEST.MF</manifestFile>
+          </archive>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-167/src/main/resources/MANIFEST.MF b/Java-base/maven-war-plugin/src/src/it/MWAR-167/src/main/resources/MANIFEST.MF
new file mode 100644
index 000000000..285550382
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-167/src/main/resources/MANIFEST.MF
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+Bundle-Name: Dummy Bundle
+Bundle-SymbolicName: dummy.bundle
+Bundle-ManifestVersion: 2
+Bundle-Version: 1.0.0.SNAPSHOT
\ No newline at end of file
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-167/verify.bsh b/Java-base/maven-war-plugin/src/src/it/MWAR-167/verify.bsh
new file mode 100644
index 000000000..fa82b4309
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-167/verify.bsh
@@ -0,0 +1,74 @@
+
+/*
+ * 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.
+ */
+
+import java.io.*;
+import org.codehaus.plexus.util.*;
+
+boolean result = true;
+
+try
+{
+    File manifest = new File( basedir, "target/MWAR-167-1.0-SNAPSHOT/META-INF/MANIFEST.MF" );
+    if ( !manifest.exists() || !manifest.isFile() )
+    {
+        System.err.println( "Manifest is missing!");
+        return false;
+    }
+    
+
+    FileInputStream fis = new FileInputStream ( manifest );
+    String manifestContent = IOUtil.toString ( fis );
+    
+    int indexOf = manifestContent.indexOf("Manifest-Version: 1.0" );
+    if ( indexOf < 0)
+    {
+    	System.err.println( "Manifest-Version header not found" );
+    	return false;
+    }
+
+	indexOf = manifestContent.indexOf("Bundle-Name: Dummy Bundle" );
+    if ( indexOf < 0)
+    {
+    	System.err.println( "Bundle-Name header not found" );
+    	return false;
+    }
+
+	indexOf = manifestContent.indexOf("Bundle-SymbolicName: dummy.bundle" );
+    if ( indexOf < 0)
+    {
+    	System.err.println( "Bundle-SymbolicName: 2" );
+    	return false;
+    }
+
+	indexOf = manifestContent.indexOf("Bundle-Version: 1.0.0.SNAPSHOT" );
+    if ( indexOf < 0)
+    {
+    	System.err.println( "Bundle-Version header not found" );
+    	return false;
+    }
+    
+}
+catch( Throwable e )
+{
+    e.printStackTrace();
+    result = false;
+}
+
+return result;
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-240/invoker.properties b/Java-base/maven-war-plugin/src/src/it/MWAR-240/invoker.properties
new file mode 100644
index 000000000..c743aa4f3
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-240/invoker.properties
@@ -0,0 +1,18 @@
+# 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.
+
+invoker.goals=clean package
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-240/pom.xml b/Java-base/maven-war-plugin/src/src/it/MWAR-240/pom.xml
new file mode 100644
index 000000000..5ac2c0d99
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-240/pom.xml
@@ -0,0 +1,43 @@
+<!--
+  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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>test</groupId>
+  <artifactId>mwar-240-test-case</artifactId>
+  <version>1.0</version>
+  <name>MWAR-240 Test case</name>
+  <packaging>war</packaging>
+  <description>Test project for reproducing an issue with classes packaging: https://issues.apache.org/jira/browse/MWAR-240</description>
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-war-plugin</artifactId>
+        <version>@pom.version@</version>
+        <configuration>
+            <failOnMissingWebXml>false</failOnMissingWebXml>
+            <archiveClasses>true</archiveClasses>
+            <attachClasses>true</attachClasses>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
\ No newline at end of file
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-240/src/main/java/org/apache/maven/plugin/war/it/Dummy.java b/Java-base/maven-war-plugin/src/src/it/MWAR-240/src/main/java/org/apache/maven/plugin/war/it/Dummy.java
new file mode 100644
index 000000000..e980d3552
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-240/src/main/java/org/apache/maven/plugin/war/it/Dummy.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.maven.plugin.war.it;
+
+/**
+ * A dummy class to show the problem with classes packaging.
+ * 
+ * @author Sergiy Shyrkov
+ */
+public class Dummy {
+
+}
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-240/verify.bsh b/Java-base/maven-war-plugin/src/src/it/MWAR-240/verify.bsh
new file mode 100644
index 000000000..fec4b9d43
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-240/verify.bsh
@@ -0,0 +1,59 @@
+
+/*
+ * 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.
+ */
+
+import java.io.*;
+import java.util.*;
+import java.util.jar.*;
+import java.util.regex.*;
+
+try
+{
+    File jarFile = new File( basedir, "target/mwar-240-test-case-1.0-classes.jar" );
+    System.out.println( "Checking for existence of " + jarFile );
+    if ( !jarFile.isFile() )
+    {
+        System.out.println( "FAILURE!" );
+        return false;
+    }
+
+    JarFile jar = new JarFile( jarFile );
+
+    String[] includedEntries = {
+        "org/apache/maven/plugin/war/it/Dummy.class",
+    };
+    for ( String included : includedEntries )
+    {
+        System.out.println( "Checking for existence of " + included );
+        if ( jar.getEntry( included ) == null )
+        {
+            System.out.println( "FAILURE!" );
+            return false;
+        }
+    }
+
+    jar.close();
+}
+catch( Throwable t )
+{
+    t.printStackTrace();
+    return false;
+}
+
+return true;
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-306/pom.xml b/Java-base/maven-war-plugin/src/src/it/MWAR-306/pom.xml
new file mode 100644
index 000000000..facc3b537
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-306/pom.xml
@@ -0,0 +1,45 @@
+<?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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>foo.bar</groupId>
+  <artifactId>MWAR-306</artifactId>
+	<version>0.0.1-SNAPSHOT</version>
+	<packaging>war</packaging>
+	<build>
+		<plugins>
+			<plugin>
+  			<groupId>@project.groupId@</groupId>
+  			<artifactId>@project.artifactId@</artifactId>
+        <version>@project.version@</version>
+				<configuration>
+					<failOnMissingWebXml>false</failOnMissingWebXml>
+					<webResources>
+						<resource>
+							<directory>src/main/webapp</directory>
+							<filtering>true</filtering>
+						</resource>
+					</webResources>
+				</configuration>
+			</plugin>
+		</plugins>
+	</build>
+</project>
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-306/src/main/webapp/index.html b/Java-base/maven-war-plugin/src/src/it/MWAR-306/src/main/webapp/index.html
new file mode 100644
index 000000000..873f9bdaf
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-306/src/main/webapp/index.html
@@ -0,0 +1,26 @@
+<!--
+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.
+-->
+<html>
+<head>
+<meta>
+<title>${project.artifactId}</title>
+</head>
+<body>${project.artifactId} @ ${project.version}</body>
+${project.name} 
+</html>
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-306/verify.groovy b/Java-base/maven-war-plugin/src/src/it/MWAR-306/verify.groovy
new file mode 100644
index 000000000..ba74120d9
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-306/verify.groovy
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+def indexHtml = new File(basedir, 'target/MWAR-306-0.0.1-SNAPSHOT/index.html');
+assert indexHtml.exists()
+
+assert indexHtml.text.contains('<body>MWAR-306 @ 0.0.1-SNAPSHOT</body>')
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-311/pom.xml b/Java-base/maven-war-plugin/src/src/it/MWAR-311/pom.xml
new file mode 100644
index 000000000..820173b11
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-311/pom.xml
@@ -0,0 +1,64 @@
+<?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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>com.ecbrodie</groupId>
+  <artifactId>MWAR-311</artifactId>
+  <version>0.0.1-SNAPSHOT</version>
+  <name>Maven War Plugin Bug</name>
+  <description>Filtering of properties files (as a web resource) broken in maven-war-plugin version 2.4.</description>
+  <packaging>war</packaging>
+  
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  	<my.maven.property>foo foo</my.maven.property>
+  </properties>
+  
+  <build>
+  	<filters>
+  		<filter>src/main/resources/default.properties</filter>
+  	</filters>
+  	<resources>
+  		<resource>
+  			<directory>src/main/resources</directory>
+  			<filtering>true</filtering>
+  		</resource>
+  	</resources>
+  	<plugins>
+  		<plugin>
+  			<groupId>@project.groupId@</groupId>
+  			<artifactId>@project.artifactId@</artifactId>
+        <version>@project.version@</version>
+  			<configuration>
+				<webResources>
+					<resource>
+						<directory>src/main/resources</directory>
+						<filtering>true</filtering>
+						<includes>
+							<include>**/app.properties</include>
+						</includes>
+					</resource>
+				</webResources>
+				<archiveClasses>true</archiveClasses>
+			</configuration>
+  		</plugin>
+  	</plugins>
+  </build>
+</project>
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-311/src/main/resources/app.properties b/Java-base/maven-war-plugin/src/src/it/MWAR-311/src/main/resources/app.properties
new file mode 100644
index 000000000..057e159b7
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-311/src/main/resources/app.properties
@@ -0,0 +1,19 @@
+# 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.
+my.maven.property=${my.maven.property}
+prop.a=${prop.a}
+prop.b=${prop.b}
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-311/src/main/resources/default.properties b/Java-base/maven-war-plugin/src/src/it/MWAR-311/src/main/resources/default.properties
new file mode 100644
index 000000000..b16902f2c
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-311/src/main/resources/default.properties
@@ -0,0 +1,18 @@
+# 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.
+prop.a=AAA
+prop.b=BBB
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-311/src/main/webapp/WEB-INF/web.xml b/Java-base/maven-war-plugin/src/src/it/MWAR-311/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 000000000..b457706f5
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-311/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,24 @@
+<?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.
+-->
+<web-app xmlns="http://java.sun.com/xml/ns/javaee"
+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
+      version="3.0"> 
+</web-app>
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-311/verify.groovy b/Java-base/maven-war-plugin/src/src/it/MWAR-311/verify.groovy
new file mode 100644
index 000000000..77599894f
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-311/verify.groovy
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+def propertiesFile = new File(basedir, 'target/MWAR-311-0.0.1-SNAPSHOT/app.properties');
+assert propertiesFile.exists()
+
+assert propertiesFile.text.contains('my.maven.property=foo foo');
+assert propertiesFile.text.contains('prop.a=AAA');
+assert propertiesFile.text.contains('prop.b=BBB');
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-314/invoker.properties b/Java-base/maven-war-plugin/src/src/it/MWAR-314/invoker.properties
new file mode 100644
index 000000000..692791cf1
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-314/invoker.properties
@@ -0,0 +1,19 @@
+# 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.
+
+invoker.goals=clean package
+invoker.debug = true
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-314/pom.xml b/Java-base/maven-war-plugin/src/src/it/MWAR-314/pom.xml
new file mode 100644
index 000000000..da9ef170c
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-314/pom.xml
@@ -0,0 +1,39 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<!--
+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.
+-->
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>mwar314</groupId>
+    <artifactId>mwar314</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+    <packaging>war</packaging>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-war-plugin</artifactId>
+                <version>@project.version@</version>
+                <configuration>
+                    <failOnMissingWebXml>false</failOnMissingWebXml>
+                    <webXml>src/main/webapp/WEB-INF/web.xml</webXml>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
\ No newline at end of file
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-314/src/main/webapp/index.jsp b/Java-base/maven-war-plugin/src/src/it/MWAR-314/src/main/webapp/index.jsp
new file mode 100644
index 000000000..41db44eef
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-314/src/main/webapp/index.jsp
@@ -0,0 +1,20 @@
+<%--
+  ~ 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.
+  --%>
+
+<% response.sendRedirect( request.getContextPath() + "/groupSummary.action" ); %>
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-326/invoker.properties b/Java-base/maven-war-plugin/src/src/it/MWAR-326/invoker.properties
new file mode 100644
index 000000000..5e07ba581
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-326/invoker.properties
@@ -0,0 +1,19 @@
+# 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.
+
+invoker.description = This test only checks if using extensions works without any issue.
+invoker.goals = clean package
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-326/pom.xml b/Java-base/maven-war-plugin/src/src/it/MWAR-326/pom.xml
new file mode 100755
index 000000000..37f123963
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-326/pom.xml
@@ -0,0 +1,46 @@
+<?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.
+-->
+
+<project
+  xmlns="http://maven.apache.org/POM/4.0.0"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.apache.maven.plugins</groupId>
+  <artifactId>maven-war-plugin-test-mwar-326</artifactId>
+  <version>1.0-SNAPSHOT</version>
+  <packaging>war</packaging>
+  <name>Maven Integration Test :: MWAR-326</name> 
+  <description>MWAR-326 integration test</description>
+  <build>
+    <plugins>
+      <plugin>
+        <inherited>false</inherited>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-war-plugin</artifactId>
+        <version>@project.version@</version>
+        <extensions>true</extensions>
+        <configuration>
+          <failOnMissingWebXml>false</failOnMissingWebXml>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-326/src/main/java/A.java b/Java-base/maven-war-plugin/src/src/it/MWAR-326/src/main/java/A.java
new file mode 100755
index 000000000..474b0a65b
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-326/src/main/java/A.java
@@ -0,0 +1,25 @@
+
+/*
+ * 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.
+ */
+
+public class A {
+    public static void main(String[] args) {
+
+    }
+}
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-326/verify.bsh b/Java-base/maven-war-plugin/src/src/it/MWAR-326/verify.bsh
new file mode 100644
index 000000000..c0a4425de
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-326/verify.bsh
@@ -0,0 +1,52 @@
+
+/*
+ * 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.
+ */
+
+import java.io.*;
+import java.util.*;
+import java.util.jar.*;
+import org.codehaus.plexus.util.*;
+
+boolean result = true;
+
+try
+{
+    File target = new File( basedir, "target" );
+    if ( !target.exists() || !target.isDirectory() )
+    {
+        System.err.println( "target file is missing or not a directory." );
+        return false;
+    }
+
+    File artifact = new File( target, "maven-war-plugin-test-mwar-326-1.0-SNAPSHOT.war" );
+    if ( !artifact.exists() )
+    {
+        System.err.println( "default artifact should exist." );
+        return false;
+    }
+
+    return true;
+}
+catch( Throwable e )
+{
+    e.printStackTrace();
+    return false;
+}
+
+return false;
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-350/pom.xml b/Java-base/maven-war-plugin/src/src/it/MWAR-350/pom.xml
new file mode 100644
index 000000000..6ef40f407
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-350/pom.xml
@@ -0,0 +1,69 @@
+<?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.
+-->
+
+<project>
+  <modelVersion>4.0.0</modelVersion>
+
+  <groupId>org.apache.maven.its.war</groupId>
+  <artifactId>maven-it-mwar350</artifactId>
+  <version>1.0</version>
+  <packaging>war</packaging>
+
+  <name>Maven Integration Test :: MWAR-350</name> 
+  <description>Test to skip WAR generation</description>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>javax.servlet</groupId>
+      <artifactId>servlet-api</artifactId>
+      <version>2.4</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>commons-logging</groupId>
+      <artifactId>commons-logging</artifactId>
+      <version>1.0.3</version>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.2</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+  
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-war-plugin</artifactId>
+        <version>@project.version@</version>
+        <configuration>
+          <skip>true</skip>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-350/src/main/java/org/apache/maven/it0016/Person.java b/Java-base/maven-war-plugin/src/src/it/MWAR-350/src/main/java/org/apache/maven/it0016/Person.java
new file mode 100644
index 000000000..4a287e77c
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-350/src/main/java/org/apache/maven/it0016/Person.java
@@ -0,0 +1,35 @@
+package org.apache.maven.it0016;
+
+/*
+ * 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.
+ */
+
+public class Person
+{
+    private String name;
+    
+    public void setName( String name )
+    {
+        this.name = name;
+    }
+    
+    public String getName()
+    {
+        return name;
+    }
+}
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-350/src/main/webapp/WEB-INF/web.xml b/Java-base/maven-war-plugin/src/src/it/MWAR-350/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 000000000..c1af95de8
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-350/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,23 @@
+<?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.
+-->
+<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
+
+<web-app >
+</web-app>
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-350/src/main/webapp/index.html b/Java-base/maven-war-plugin/src/src/it/MWAR-350/src/main/webapp/index.html
new file mode 100644
index 000000000..8e81e877d
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-350/src/main/webapp/index.html
@@ -0,0 +1,23 @@
+<!--
+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.
+-->
+<html>
+  <body>
+    Hello World
+  </body>
+</html>
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-350/verify.bsh b/Java-base/maven-war-plugin/src/src/it/MWAR-350/verify.bsh
new file mode 100644
index 000000000..9e5c87990
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-350/verify.bsh
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+import java.io.*;
+import java.util.*;
+import java.util.jar.*;
+import java.util.regex.*;
+
+try
+{
+    File explodedDir = new File( basedir, "target/maven-it-mwar350-1.0" );
+    System.out.println( "Checking for existence of exploded directory " + explodedDir );
+    if ( explodedDir.isDirectory() )
+    {
+        System.out.println( "FAILURE! The directory " + explodedDir + " does exist." );
+        return false;
+    }
+
+
+    File warFile = new File( basedir, "target/maven-it-mwar350-1.0.war" );
+    System.out.println( "Checking for existence of " + warFile );
+    if ( warFile.isFile() )
+    {
+        System.out.println( "FAILURE! The generated file should have not be there." );
+        return false;
+    }
+
+}
+catch( Throwable t )
+{
+    t.printStackTrace();
+    return false;
+}
+
+return true;
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-352_custom-webXml/pom.xml b/Java-base/maven-war-plugin/src/src/it/MWAR-352_custom-webXml/pom.xml
new file mode 100644
index 000000000..12905e211
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-352_custom-webXml/pom.xml
@@ -0,0 +1,46 @@
+<?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.
+-->
+
+<project>
+  <modelVersion>4.0.0</modelVersion>
+
+  <groupId>org.apache.maven.plugins.war.its</groupId>
+  <artifactId>mwar-352</artifactId>
+  <version>1.0-SNAPSHOT</version>
+  <packaging>war</packaging>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-war-plugin</artifactId>
+        <version>@project.version@</version>
+        <configuration>
+          <webXml>src/main/webconfig/release/web.xml</webXml>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-352_custom-webXml/src/main/webapp/WEB-INF/web.xml b/Java-base/maven-war-plugin/src/src/it/MWAR-352_custom-webXml/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 000000000..d8f4f21de
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-352_custom-webXml/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,22 @@
+<?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.
+-->
+<web-app>
+  <!-- from src/main/webapp/WEB-INF/web.xml -->
+</web-app>
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-352_custom-webXml/src/main/webconfig/release/web.xml b/Java-base/maven-war-plugin/src/src/it/MWAR-352_custom-webXml/src/main/webconfig/release/web.xml
new file mode 100644
index 000000000..a7b8744cf
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-352_custom-webXml/src/main/webconfig/release/web.xml
@@ -0,0 +1,22 @@
+<?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.
+-->
+<web-app>
+  <!-- from src/main/webconfig/release/web.xml -->
+</web-app>
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-352_custom-webXml/verify.groovy b/Java-base/maven-war-plugin/src/src/it/MWAR-352_custom-webXml/verify.groovy
new file mode 100644
index 000000000..753bf8465
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-352_custom-webXml/verify.groovy
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+def warFile = new java.util.jar.JarFile( new File(basedir,"target/mwar-352-1.0-SNAPSHOT.war"), false)
+def webXml = warFile.getEntry('WEB-INF/web.xml')
+assert webXml != null
+assert warFile.getInputStream( webXml).text.contains('from src/main/webconfig/release/web.xml')
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-371/custom/pom.xml b/Java-base/maven-war-plugin/src/src/it/MWAR-371/custom/pom.xml
new file mode 100644
index 000000000..b2aa1976a
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-371/custom/pom.xml
@@ -0,0 +1,65 @@
+<?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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<groupId>mwar371</groupId>
+		<artifactId>mwar371</artifactId>
+		<version>1.0-SNAPSHOT</version>
+	</parent>
+	<artifactId>custom</artifactId>
+	<packaging>war</packaging>
+	<dependencies>
+		<dependency>
+			<groupId>mwar371</groupId>
+			<artifactId>generic</artifactId>
+			<version>1.0-SNAPSHOT</version>
+			<type>war</type>
+		</dependency>
+	</dependencies>
+	<build>
+
+		<plugins>
+			<plugin>
+				<artifactId>maven-war-plugin</artifactId>
+				<configuration>
+					<webResources>
+						<webResource>
+							<directory>src/main/custom</directory>
+							<includes>
+								<include>a1.txt</include>
+							</includes>
+							<targetPath>x/</targetPath>
+						</webResource>
+						<webResource>
+							<directory>src/main/custom</directory>
+							<includes>
+								<include>a2.txt</include>
+							</includes>
+							<targetPath>x</targetPath>
+						</webResource>
+					</webResources>
+				</configuration>
+			</plugin>
+		</plugins>
+
+	</build>
+</project>
\ No newline at end of file
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-371/custom/src/main/custom/a1.txt b/Java-base/maven-war-plugin/src/src/it/MWAR-371/custom/src/main/custom/a1.txt
new file mode 100644
index 000000000..7fe810a0c
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-371/custom/src/main/custom/a1.txt
@@ -0,0 +1,18 @@
+# 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.
+
+i'm custom
\ No newline at end of file
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-371/custom/src/main/custom/a2.txt b/Java-base/maven-war-plugin/src/src/it/MWAR-371/custom/src/main/custom/a2.txt
new file mode 100644
index 000000000..7fe810a0c
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-371/custom/src/main/custom/a2.txt
@@ -0,0 +1,18 @@
+# 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.
+
+i'm custom
\ No newline at end of file
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-371/generic/pom.xml b/Java-base/maven-war-plugin/src/src/it/MWAR-371/generic/pom.xml
new file mode 100644
index 000000000..beeef48a2
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-371/generic/pom.xml
@@ -0,0 +1,29 @@
+<?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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>mwar371</groupId>
+    <artifactId>mwar371</artifactId>
+    <version>1.0-SNAPSHOT</version>
+  </parent>
+  <artifactId>generic</artifactId>
+  <packaging>war</packaging>
+</project>
\ No newline at end of file
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-371/generic/src/main/webapp/x/a1.txt b/Java-base/maven-war-plugin/src/src/it/MWAR-371/generic/src/main/webapp/x/a1.txt
new file mode 100644
index 000000000..fc4dee13c
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-371/generic/src/main/webapp/x/a1.txt
@@ -0,0 +1,18 @@
+# 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.
+
+I'm generic
\ No newline at end of file
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-371/generic/src/main/webapp/x/a2.txt b/Java-base/maven-war-plugin/src/src/it/MWAR-371/generic/src/main/webapp/x/a2.txt
new file mode 100644
index 000000000..fc4dee13c
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-371/generic/src/main/webapp/x/a2.txt
@@ -0,0 +1,18 @@
+# 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.
+
+I'm generic
\ No newline at end of file
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-371/generic/src/main/webapp/x/a3.txt b/Java-base/maven-war-plugin/src/src/it/MWAR-371/generic/src/main/webapp/x/a3.txt
new file mode 100644
index 000000000..fc4dee13c
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-371/generic/src/main/webapp/x/a3.txt
@@ -0,0 +1,18 @@
+# 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.
+
+I'm generic
\ No newline at end of file
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-371/pom.xml b/Java-base/maven-war-plugin/src/src/it/MWAR-371/pom.xml
new file mode 100644
index 000000000..1f72884fb
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-371/pom.xml
@@ -0,0 +1,51 @@
+<?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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<groupId>mwar371</groupId>
+	<artifactId>mwar371</artifactId>
+	<version>1.0-SNAPSHOT</version>
+	<packaging>pom</packaging>
+  <name>Maven Integration Test :: MWAR-371</name> 
+  <description>MWAR-371 integration test</description>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+  	
+	<modules>
+		<module>generic</module>
+		<module>custom</module>
+	</modules>
+	<build>
+		<pluginManagement>
+			<plugins>
+				<plugin>
+					<artifactId>maven-war-plugin</artifactId>
+					<version>@project.version@</version>
+					<configuration>
+						<failOnMissingWebXml>false</failOnMissingWebXml>
+					</configuration>
+				</plugin>
+			</plugins>
+		</pluginManagement>
+	</build>
+</project>
\ No newline at end of file
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-371/verify.groovy b/Java-base/maven-war-plugin/src/src/it/MWAR-371/verify.groovy
new file mode 100644
index 000000000..e66bcd5ec
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-371/verify.groovy
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+
+boolean checkFile( String fileName, String artifact, String module )
+{
+    def customA1 = new File( basedir, "${artifact}/target/${artifact}-1.0-SNAPSHOT/x/${fileName}" )
+    if ( ! customA1.exists() )
+    {
+        System.err.println( "${artifact}/target/${artifact}-1.0-SNAPSHOT/x/${fileName} does not exist." )
+        return false
+    }
+    if ( ! customA1.text.contains( module ) )
+    {
+        System.err.println( "${artifact}/target/${artifact}-1.0-SNAPSHOT/x/${fileName} is not ${module}." )
+        return false
+    }
+    return true
+}
+
+boolean checkFile( String fileName, String module )
+{
+    return checkFile( fileName, module, module )
+}
+
+try {
+    if ( ! checkFile( "a1.txt", "custom" ) )
+    {
+        return false
+    }
+    if ( ! checkFile( "a2.txt", "custom" ) )
+    {
+        return false
+    }
+    if ( ! checkFile( "a3.txt", "custom", "generic" ) )
+    {
+        return false
+    }
+    if ( ! checkFile( "a1.txt", "generic" ) )
+    {
+        return false
+    }
+    if ( ! checkFile( "a2.txt", "generic" ) )
+    {
+        return false
+    }
+    if ( ! checkFile( "a3.txt", "generic" ) )
+    {
+        return false
+    }
+}
+catch ( Throwable e )
+{
+    e.printStackTrace()
+    return false
+}
+
+return true
+
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-396_no-servlet30/invoker.properties b/Java-base/maven-war-plugin/src/src/it/MWAR-396_no-servlet30/invoker.properties
new file mode 100644
index 000000000..f2a7dfb44
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-396_no-servlet30/invoker.properties
@@ -0,0 +1,18 @@
+# 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.
+
+invoker.buildResult = failure
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-396_no-servlet30/pom.xml b/Java-base/maven-war-plugin/src/src/it/MWAR-396_no-servlet30/pom.xml
new file mode 100644
index 000000000..5fa6d853f
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-396_no-servlet30/pom.xml
@@ -0,0 +1,66 @@
+<?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.
+-->
+
+<project>
+  <modelVersion>4.0.0</modelVersion>
+
+  <groupId>org.apache.maven.its.war</groupId>
+  <artifactId>maven-it-mwar396</artifactId>
+  <version>1.0</version>
+  <packaging>war</packaging>
+
+  <name>Maven Integration Test :: MWAR-396</name> 
+  <description>Test that a web.xml is required when project does not depend on Servlet 3.0 or newer</description>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>javax.servlet</groupId>
+      <artifactId>servlet-api</artifactId>
+      <version>2.4</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>commons-logging</groupId>
+      <artifactId>commons-logging</artifactId>
+      <version>1.0.3</version>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.2</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+  
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-war-plugin</artifactId>
+        <version>@project.version@</version>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-396_servlet30/pom.xml b/Java-base/maven-war-plugin/src/src/it/MWAR-396_servlet30/pom.xml
new file mode 100644
index 000000000..2244d1599
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-396_servlet30/pom.xml
@@ -0,0 +1,66 @@
+<?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.
+-->
+
+<project>
+  <modelVersion>4.0.0</modelVersion>
+
+  <groupId>org.apache.maven.its.war</groupId>
+  <artifactId>maven-it-mwar396_servlet30</artifactId>
+  <version>1.0</version>
+  <packaging>war</packaging>
+
+  <name>Maven Integration Test :: MWAR-396</name> 
+  <description>Test that no web.xml is required when project depends on Servlet 3.0 or newer</description>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>javax.servlet</groupId>
+      <artifactId>javax.servlet-api</artifactId>
+      <version>3.0.1</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>commons-logging</groupId>
+      <artifactId>commons-logging</artifactId>
+      <version>1.0.3</version>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.2</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+  
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-war-plugin</artifactId>
+        <version>@project.version@</version>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-396_servlet30/verify.bsh b/Java-base/maven-war-plugin/src/src/it/MWAR-396_servlet30/verify.bsh
new file mode 100644
index 000000000..402a3ca27
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-396_servlet30/verify.bsh
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+import java.io.*;
+import java.util.*;
+import java.util.jar.*;
+import java.util.regex.*;
+
+try
+{
+    File explodedDir = new File( basedir, "target/maven-it-mwar396_servlet30-1.0" );
+    System.out.println( "Checking for existence of exploded directory " + explodedDir );
+    if ( !explodedDir.exists() )
+    {
+        System.out.println( "FAILURE! The directory " + explodedDir + " does not exist." );
+        return false;
+    }
+    
+    File webInfFile = new File( explodedDir, "WEB-INF/web.xml" );
+    if ( webInfFile.exists() )
+    {
+        System.err.println( "FAILURE! The file web.xml should not be present." );
+        return false;
+    }
+
+}
+catch( Throwable t )
+{
+    t.printStackTrace();
+    return false;
+}
+
+return true;
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-427_update-without-clean/invoker.properties b/Java-base/maven-war-plugin/src/src/it/MWAR-427_update-without-clean/invoker.properties
new file mode 100644
index 000000000..ea3a6224b
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-427_update-without-clean/invoker.properties
@@ -0,0 +1,20 @@
+# 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.
+
+invoker.goals.1=package
+invoker.goals.2=groovy:execute
+invoker.goals.3=package
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-427_update-without-clean/pom.xml b/Java-base/maven-war-plugin/src/src/it/MWAR-427_update-without-clean/pom.xml
new file mode 100644
index 000000000..a0d714624
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-427_update-without-clean/pom.xml
@@ -0,0 +1,79 @@
+<?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.
+-->
+
+<project>
+  <modelVersion>4.0.0</modelVersion>
+
+  <groupId>org.apache.maven.its.war</groupId>
+  <artifactId>mwar427</artifactId>
+  <version>1.0-SNAPSHOT</version>
+  <packaging>war</packaging>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-war-plugin</artifactId>
+        <version>@project.version@</version>
+        <configuration>
+          <archiveClasses>true</archiveClasses>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.codehaus.gmaven</groupId>
+        <artifactId>groovy-maven-plugin</artifactId>
+        <version>2.0</version>
+        <configuration>
+          <source>
+            def fileToModify = new File(project.basedir, 'pom.xml')
+            processFileInplace(fileToModify) { text ->
+              text.replaceAll(/1.4.6/,'1.4.5')
+            }
+            def processFileInplace(file, Closure processText) {
+              file.write(processText(file.text))
+            }
+            
+            new File('src/main/webapp/root.html').renameTo 'src/main/webapp/index.html'
+          </source>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+  <dependencies>
+    <dependency>
+      <groupId>javax.servlet</groupId>
+      <artifactId>javax.servlet-api</artifactId>
+      <version>3.0.1</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.codehaus.plexus</groupId>
+      <artifactId>plexus-utils</artifactId>
+      <version>1.4.6</version>
+    </dependency>
+  </dependencies>
+  
+</project>
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-427_update-without-clean/src/main/resources/resource.txt b/Java-base/maven-war-plugin/src/src/it/MWAR-427_update-without-clean/src/main/resources/resource.txt
new file mode 100644
index 000000000..13a83393a
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-427_update-without-clean/src/main/resources/resource.txt
@@ -0,0 +1,16 @@
+# 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.
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-427_update-without-clean/src/main/webapp/index.html b/Java-base/maven-war-plugin/src/src/it/MWAR-427_update-without-clean/src/main/webapp/index.html
new file mode 100644
index 000000000..8809bcf35
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-427_update-without-clean/src/main/webapp/index.html
@@ -0,0 +1,23 @@
+<!--
+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.
+-->
+<html>
+  <body>
+    Hello World
+  </body>
+</html>
\ No newline at end of file
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-427_update-without-clean/verify.groovy b/Java-base/maven-war-plugin/src/src/it/MWAR-427_update-without-clean/verify.groovy
new file mode 100644
index 000000000..5fdf4744d
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-427_update-without-clean/verify.groovy
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+def warFile = new java.util.jar.JarFile( new File(basedir,"target/mwar427-1.0-SNAPSHOT.war"), false)
+assert warFile.getEntry('WEB-INF/lib/plexus-utils-1.4.5.jar') != null
+assert warFile.getEntry('WEB-INF/lib/mwar427-1.0-SNAPSHOT.jar') != null
+assert warFile.getEntry('index.html') != null
+
+assert warFile.getEntry('WEB-INF/lib/plexus-utils-1.4.6.jar') == null
+assert warFile.getEntry('root.html') == null
\ No newline at end of file
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-430_jakarta-servlet/invoker.properties b/Java-base/maven-war-plugin/src/src/it/MWAR-430_jakarta-servlet/invoker.properties
new file mode 100644
index 000000000..9695a95b5
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-430_jakarta-servlet/invoker.properties
@@ -0,0 +1,19 @@
+# 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.
+
+invoker.java.version = 1.8+
+
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-430_jakarta-servlet/pom.xml b/Java-base/maven-war-plugin/src/src/it/MWAR-430_jakarta-servlet/pom.xml
new file mode 100644
index 000000000..8f773b1cb
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-430_jakarta-servlet/pom.xml
@@ -0,0 +1,66 @@
+<?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.
+-->
+
+<project>
+  <modelVersion>4.0.0</modelVersion>
+
+  <groupId>org.apache.maven.its.war</groupId>
+  <artifactId>maven-it-mwar-430</artifactId>
+  <version>1.0</version>
+  <packaging>war</packaging>
+
+  <name>Maven Integration Test :: MWAR-430</name> 
+  <description>Test that no web.xml is required when project depends on Jakarta Servlet 5.0 or newer</description>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>jakarta.servlet</groupId>
+      <artifactId>jakarta.servlet-api</artifactId>
+      <version>5.0.0-M1</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>commons-logging</groupId>
+      <artifactId>commons-logging</artifactId>
+      <version>1.0.3</version>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.2</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+  
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-war-plugin</artifactId>
+        <version>@project.version@</version>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-430_jakarta-servlet/verify.bsh b/Java-base/maven-war-plugin/src/src/it/MWAR-430_jakarta-servlet/verify.bsh
new file mode 100644
index 000000000..3c7e8b5e1
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-430_jakarta-servlet/verify.bsh
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+import java.io.*;
+import java.util.*;
+import java.util.jar.*;
+import java.util.regex.*;
+
+try
+{
+    File explodedDir = new File( basedir, "target/maven-it-mwar-430-1.0" );
+    System.out.println( "Checking for existence of exploded directory " + explodedDir );
+    if ( !explodedDir.exists() )
+    {
+        System.out.println( "FAILURE! The directory " + explodedDir + " does not exist." );
+        return false;
+    }
+    
+    File webInfFile = new File( explodedDir, "WEB-INF/web.xml" );
+    if ( webInfFile.exists() )
+    {
+        System.err.println( "FAILURE! The file web.xml should not be present." );
+        return false;
+    }
+
+}
+catch( Throwable t )
+{
+    t.printStackTrace();
+    return false;
+}
+
+return true;
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-62/invoker.properties b/Java-base/maven-war-plugin/src/src/it/MWAR-62/invoker.properties
new file mode 100644
index 000000000..7e6fbfd9f
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-62/invoker.properties
@@ -0,0 +1,18 @@
+# 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.
+
+invoker.goals=clean war:exploded
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-62/pom.xml b/Java-base/maven-war-plugin/src/src/it/MWAR-62/pom.xml
new file mode 100644
index 000000000..9c97e29bf
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-62/pom.xml
@@ -0,0 +1,50 @@
+<?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.
+-->
+<project xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd' xmlns='http://maven.apache.org/POM/4.0.0'>
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>testwar</groupId>
+  <artifactId>MWAR-62</artifactId>
+  <packaging>war</packaging>
+  <version>1.0-SNAPSHOT</version>
+  <name>MWAR-62 Maven Webapp</name>
+  <url>http://maven.apache.org</url>
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.1</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+ <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-war-plugin</artifactId>
+        <!--version>2.0.2</version-->
+        <version>@pom.version@</version>
+        <configuration>
+          <webappDirectory>${project.build.directory}/webAppDirectory</webappDirectory>
+          <warSourceDirectory>src/main/webapp</warSourceDirectory>
+          <warSourceExcludes>**/*dev.properties,**/*test.properties</warSourceExcludes>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-62/src/main/webapp/dev.properties b/Java-base/maven-war-plugin/src/src/it/MWAR-62/src/main/webapp/dev.properties
new file mode 100644
index 000000000..eb7ffe692
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-62/src/main/webapp/dev.properties
@@ -0,0 +1,18 @@
+# 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.
+
+foo dev
\ No newline at end of file
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-62/src/main/webapp/test.properties b/Java-base/maven-war-plugin/src/src/it/MWAR-62/src/main/webapp/test.properties
new file mode 100644
index 000000000..eb7ffe692
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-62/src/main/webapp/test.properties
@@ -0,0 +1,18 @@
+# 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.
+
+foo dev
\ No newline at end of file
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-62/src/main/webapp/web.xml b/Java-base/maven-war-plugin/src/src/it/MWAR-62/src/main/webapp/web.xml
new file mode 100644
index 000000000..6a8fa709e
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-62/src/main/webapp/web.xml
@@ -0,0 +1,24 @@
+<!DOCTYPE web-app PUBLIC
+ "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+ "http://java.sun.com/dtd/web-app_2_3.dtd" >
+<!--
+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.
+-->
+<web-app>
+  <display-name>Archetype Created Web Application</display-name>
+</web-app>
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-62/verify.bsh b/Java-base/maven-war-plugin/src/src/it/MWAR-62/verify.bsh
new file mode 100644
index 000000000..0eeb6d9b1
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-62/verify.bsh
@@ -0,0 +1,61 @@
+
+/*
+ * 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.
+ */
+
+import java.io.*;
+import org.codehaus.plexus.util.*;
+
+boolean result = true;
+
+try
+{
+    File target = new File( basedir, "target" );
+    if ( !target.exists() || !target.isDirectory() )
+    {
+        System.err.println( "target file is missing or not a directory." );
+        return false;
+    }
+    File webAppDirectory = new File( target, "webAppDirectory" );
+    if ( !webAppDirectory.exists() || !webAppDirectory.isDirectory() )
+    {
+        System.err.println( "webAppDirectory is missing or a not directory." );
+        return false;
+    }
+    File devProperties = new File( webAppDirectory, "dev.properties" );
+    if ( devProperties.exists() )
+    {
+        System.err.println( "dev.properties has not been excluded." );
+        return false;
+    }
+
+    File testProperties = new File( webAppDirectory, "test.properties" );
+    if ( testProperties.exists() )
+    {
+        System.err.println( "test.properties has not been excluded." );
+        return false;
+    }
+
+}
+catch( Throwable e )
+{
+    e.printStackTrace();
+    result = false;
+}
+
+return result;
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-96/pom.xml b/Java-base/maven-war-plugin/src/src/it/MWAR-96/pom.xml
new file mode 100644
index 000000000..3a303a5e8
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-96/pom.xml
@@ -0,0 +1,51 @@
+<?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.
+-->
+<project xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd' xmlns='http://maven.apache.org/POM/4.0.0'>
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>testwar</groupId>
+  <artifactId>MWAR-96</artifactId>
+  <packaging>war</packaging>
+  <version>1.0-SNAPSHOT</version>
+  <name>MWAR-96 MWAR-144 Tests</name>
+  <url>http://maven.apache.org</url>
+ <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-war-plugin</artifactId>
+        <version>@pom.version@</version>
+        <configuration>
+          <warSourceDirectory>src/main/webapp</warSourceDirectory>
+          <filters>
+            <filter>src/main/filters/filter.properties</filter>
+          </filters>
+          <webResources>
+            <resource>
+              <filtering>true</filtering>
+              <directory>src/main/webapp</directory>
+              <includes>
+                <include>index.jsp</include>
+              </includes>
+            </resource>
+          </webResources>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-96/src/main/filters/filter.properties b/Java-base/maven-war-plugin/src/src/it/MWAR-96/src/main/filters/filter.properties
new file mode 100644
index 000000000..0b24f47c7
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-96/src/main/filters/filter.properties
@@ -0,0 +1,19 @@
+#/*
+# * 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.
+# */
+warPluginFilterConfigurationProperty=okitworks
\ No newline at end of file
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-96/src/main/webapp/WEB-INF/web.xml b/Java-base/maven-war-plugin/src/src/it/MWAR-96/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 000000000..6a8fa709e
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-96/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,24 @@
+<!DOCTYPE web-app PUBLIC
+ "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+ "http://java.sun.com/dtd/web-app_2_3.dtd" >
+<!--
+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.
+-->
+<web-app>
+  <display-name>Archetype Created Web Application</display-name>
+</web-app>
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-96/src/main/webapp/index.jsp b/Java-base/maven-war-plugin/src/src/it/MWAR-96/src/main/webapp/index.jsp
new file mode 100755
index 000000000..2321faffc
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-96/src/main/webapp/index.jsp
@@ -0,0 +1,22 @@
+<!--
+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.
+-->
+<tr><td>java version</td><td>java version : ${java.version}</td></tr>
+<tr><td>Project</td><td>${pom.name}</td></tr>
+<tr><td>Version</td><td>${pom.version}</td></tr>
+<tr><td>custom filter</td><td>${warPluginFilterConfigurationProperty}</td></tr>
\ No newline at end of file
diff --git a/Java-base/maven-war-plugin/src/src/it/MWAR-96/verify.bsh b/Java-base/maven-war-plugin/src/src/it/MWAR-96/verify.bsh
new file mode 100644
index 000000000..18a6258eb
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/MWAR-96/verify.bsh
@@ -0,0 +1,74 @@
+
+/*
+ * 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.
+ */
+
+import java.io.*;
+import org.codehaus.plexus.util.*;
+
+boolean result = true;
+
+try
+{
+    File target = new File( basedir, "target" );
+    if ( !target.exists() || !target.isDirectory() )
+    {
+        System.err.println( "target file is missing or not a directory." );
+        return false;
+    }
+
+    File webappDirectory = new File( target, "MWAR-96-1.0-SNAPSHOT" );
+    if ( !webappDirectory.exists() || !webappDirectory.isDirectory() )
+    {
+        System.err.println( "webappDirectory is missing or not a directory." );
+        return false;
+    }
+
+    File param = new File( webappDirectory, "index.jsp" );
+    if ( !param.exists() || param.isDirectory() )
+    {
+        System.err.println( "index.jsp file is missing or a directory." );
+        return false;
+    }
+    String paramContent = FileUtils.fileRead( param );
+
+    String javaVersion = System.getProperty( "java.version" );
+    int indexOf = paramContent.indexOf( "<td>java version : " + javaVersion + "</td>" );
+    if ( indexOf < 0 )
+    {
+        paramContent = paramContent.substring( paramContent.indexOf( "<td>java version : " ) );
+        System.err.println( "index.jsp not contains <td>java version : " + javaVersion + "</td> but "
+            + paramContent.substring( 0, paramContent.indexOf( "</td>" ) + 5 ) );
+        return false;
+    }
+
+    indexOf = paramContent.indexOf("<td>okitworks</td>" );
+    if ( indexOf < 0 )
+    {
+        System.err.println( "index.jsp not contains <td>okitworks</td>" );
+        return false;
+    }
+
+}
+catch( Throwable e )
+{
+    e.printStackTrace();
+    result = false;
+}
+
+return result;
diff --git a/Java-base/maven-war-plugin/src/src/it/archiveClasses/pom.xml b/Java-base/maven-war-plugin/src/src/it/archiveClasses/pom.xml
new file mode 100644
index 000000000..a7c516631
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/archiveClasses/pom.xml
@@ -0,0 +1,70 @@
+<?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.
+-->
+
+<project>
+  <modelVersion>4.0.0</modelVersion>
+
+  <groupId>org.apache.maven.its.mwar-45</groupId>
+  <artifactId>maven-it-mwar-45</artifactId>
+  <version>1.0</version>
+  <packaging>war</packaging>
+
+  <name>Maven Integration Test :: MWAR-45</name> 
+  <description>Test a WAR generation with archiveClasses=true</description>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <project.build.outputTimestamp>2020-06-06T06:50:15Z</project.build.outputTimestamp>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>javax.servlet</groupId>
+      <artifactId>servlet-api</artifactId>
+      <version>2.4</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>commons-logging</groupId>
+      <artifactId>commons-logging</artifactId>
+      <version>1.0.3</version>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.2</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+  
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-war-plugin</artifactId>
+        <version>@project.version@</version>
+        <configuration>
+          <archiveClasses>true</archiveClasses>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/Java-base/maven-war-plugin/src/src/it/archiveClasses/src/main/java/org/apache/maven/it0016/Person.java b/Java-base/maven-war-plugin/src/src/it/archiveClasses/src/main/java/org/apache/maven/it0016/Person.java
new file mode 100644
index 000000000..4a287e77c
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/archiveClasses/src/main/java/org/apache/maven/it0016/Person.java
@@ -0,0 +1,35 @@
+package org.apache.maven.it0016;
+
+/*
+ * 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.
+ */
+
+public class Person
+{
+    private String name;
+    
+    public void setName( String name )
+    {
+        this.name = name;
+    }
+    
+    public String getName()
+    {
+        return name;
+    }
+}
diff --git a/Java-base/maven-war-plugin/src/src/it/archiveClasses/src/main/webapp/WEB-INF/web.xml b/Java-base/maven-war-plugin/src/src/it/archiveClasses/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 000000000..c1af95de8
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/archiveClasses/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,23 @@
+<?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.
+-->
+<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
+
+<web-app >
+</web-app>
diff --git a/Java-base/maven-war-plugin/src/src/it/archiveClasses/src/main/webapp/index.html b/Java-base/maven-war-plugin/src/src/it/archiveClasses/src/main/webapp/index.html
new file mode 100644
index 000000000..8e81e877d
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/archiveClasses/src/main/webapp/index.html
@@ -0,0 +1,23 @@
+<!--
+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.
+-->
+<html>
+  <body>
+    Hello World
+  </body>
+</html>
diff --git a/Java-base/maven-war-plugin/src/src/it/archiveClasses/verify.bsh b/Java-base/maven-war-plugin/src/src/it/archiveClasses/verify.bsh
new file mode 100644
index 000000000..9b3da7509
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/archiveClasses/verify.bsh
@@ -0,0 +1,99 @@
+/*
+ * 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.
+ */
+
+import java.io.*;
+import java.util.*;
+import java.util.jar.*;
+import java.util.regex.*;
+
+try
+{
+    File explodedDir = new File( basedir, "target/maven-it-mwar-45-1.0" );
+    System.out.println( "Checking for existence of exploded directory " + explodedDir );
+    if ( !explodedDir.isDirectory() )
+    {
+        System.out.println( "FAILURE!" );
+        return false;
+    }
+
+    String[] expectedPaths = {
+            "index.html",
+            "WEB-INF/lib/commons-logging-1.0.3.jar",
+            "WEB-INF/lib/maven-it-mwar-45-1.0.jar",
+    };
+    for ( String path : expectedPaths )
+    {
+        File file = new File( explodedDir, path );
+        System.out.println( "Checking for existence of " + file );
+        if ( !file.exists() )
+        {
+            System.out.println( "FAILURE!" );
+            return false;
+        }
+    }
+
+    String[] unexpectedPaths = {
+            "WEB-INF/classes/org/apache/maven/it0016/Person.class",
+            "WEB-INF/lib/servlet-api-2.4.jar",
+    };
+    for ( String path : unexpectedPaths )
+    {
+        File file = new File( explodedDir, path );
+        System.out.println( "Checking for absence of " + file );
+        if ( file.exists() )
+        {
+            System.out.println( "FAILURE!" );
+            return false;
+        }
+    }
+
+    File warFile = new File( basedir, "target/maven-it-mwar-45-1.0.war" );
+    System.out.println( "Checking for existence of " + warFile );
+    if ( !warFile.isFile() )
+    {
+        System.out.println( "FAILURE!" );
+        return false;
+    }
+
+    JarFile war = new JarFile( warFile );
+
+    String[] includedEntries = {
+        "index.html",
+        "WEB-INF/lib/maven-it-mwar-45-1.0.jar",
+        "WEB-INF/lib/commons-logging-1.0.3.jar",
+    };
+    for ( String included : includedEntries )
+    {
+        System.out.println( "Checking for existence of " + included );
+        if ( war.getEntry( included ) == null )
+        {
+            System.out.println( "FAILURE!" );
+            return false;
+        }
+    }
+
+    war.close();
+}
+catch( Throwable t )
+{
+    t.printStackTrace();
+    return false;
+}
+
+return true;
diff --git a/Java-base/maven-war-plugin/src/src/it/default/pom.xml b/Java-base/maven-war-plugin/src/src/it/default/pom.xml
new file mode 100644
index 000000000..10554a86b
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/default/pom.xml
@@ -0,0 +1,66 @@
+<?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.
+-->
+
+<project>
+  <modelVersion>4.0.0</modelVersion>
+
+  <groupId>org.apache.maven.its.it0016</groupId>
+  <artifactId>maven-it-it0016</artifactId>
+  <version>1.0</version>
+  <packaging>war</packaging>
+
+  <name>Maven Integration Test :: it0016</name> 
+  <description>Test a WAR generation</description>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>javax.servlet</groupId>
+      <artifactId>servlet-api</artifactId>
+      <version>2.4</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>commons-logging</groupId>
+      <artifactId>commons-logging</artifactId>
+      <version>1.0.3</version>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.2</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+  
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-war-plugin</artifactId>
+        <version>@project.version@</version>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/Java-base/maven-war-plugin/src/src/it/default/src/main/java/org/apache/maven/it0016/Person.java b/Java-base/maven-war-plugin/src/src/it/default/src/main/java/org/apache/maven/it0016/Person.java
new file mode 100644
index 000000000..4a287e77c
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/default/src/main/java/org/apache/maven/it0016/Person.java
@@ -0,0 +1,35 @@
+package org.apache.maven.it0016;
+
+/*
+ * 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.
+ */
+
+public class Person
+{
+    private String name;
+    
+    public void setName( String name )
+    {
+        this.name = name;
+    }
+    
+    public String getName()
+    {
+        return name;
+    }
+}
diff --git a/Java-base/maven-war-plugin/src/src/it/default/src/main/webapp/WEB-INF/web.xml b/Java-base/maven-war-plugin/src/src/it/default/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 000000000..c1af95de8
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/default/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,23 @@
+<?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.
+-->
+<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
+
+<web-app >
+</web-app>
diff --git a/Java-base/maven-war-plugin/src/src/it/default/src/main/webapp/index.html b/Java-base/maven-war-plugin/src/src/it/default/src/main/webapp/index.html
new file mode 100644
index 000000000..8e81e877d
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/default/src/main/webapp/index.html
@@ -0,0 +1,23 @@
+<!--
+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.
+-->
+<html>
+  <body>
+    Hello World
+  </body>
+</html>
diff --git a/Java-base/maven-war-plugin/src/src/it/default/verify.bsh b/Java-base/maven-war-plugin/src/src/it/default/verify.bsh
new file mode 100644
index 000000000..af15a8196
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/default/verify.bsh
@@ -0,0 +1,97 @@
+/*
+ * 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.
+ */
+
+import java.io.*;
+import java.util.*;
+import java.util.jar.*;
+import java.util.regex.*;
+
+try
+{
+    File explodedDir = new File( basedir, "target/maven-it-it0016-1.0" );
+    System.out.println( "Checking for existence of exploded directory " + explodedDir );
+    if ( !explodedDir.isDirectory() )
+    {
+        System.out.println( "FAILURE!" );
+        return false;
+    }
+
+    String[] expectedPaths = {
+            "index.html",
+            "WEB-INF/classes/org/apache/maven/it0016/Person.class",
+            "WEB-INF/lib/commons-logging-1.0.3.jar",
+    };
+    for ( String path : expectedPaths )
+    {
+        File file = new File( explodedDir, path );
+        System.out.println( "Checking for existence of " + file );
+        if ( !file.exists() )
+        {
+            System.out.println( "FAILURE!" );
+            return false;
+        }
+    }
+
+    String[] unexpectedPaths = {
+            "WEB-INF/lib/servlet-api-2.4.jar",
+    };
+    for ( String path : unexpectedPaths )
+    {
+        File file = new File( explodedDir, path );
+        System.out.println( "Checking for absence of " + file );
+        if ( file.exists() )
+        {
+            System.out.println( "FAILURE!" );
+            return false;
+        }
+    }
+
+    File warFile = new File( basedir, "target/maven-it-it0016-1.0.war" );
+    System.out.println( "Checking for existence of " + warFile );
+    if ( !warFile.isFile() )
+    {
+        System.out.println( "FAILURE!" );
+        return false;
+    }
+
+    JarFile war = new JarFile( warFile );
+
+    String[] includedEntries = {
+        "WEB-INF/classes/org/apache/maven/it0016/Person.class",
+        "WEB-INF/lib/commons-logging-1.0.3.jar",
+    };
+    for ( String included : includedEntries )
+    {
+        System.out.println( "Checking for existence of " + included );
+        if ( war.getEntry( included ) == null )
+        {
+            System.out.println( "FAILURE!" );
+            return false;
+        }
+    }
+
+    war.close();
+}
+catch( Throwable t )
+{
+    t.printStackTrace();
+    return false;
+}
+
+return true;
diff --git a/Java-base/maven-war-plugin/src/src/it/manifest-content/pom.xml b/Java-base/maven-war-plugin/src/src/it/manifest-content/pom.xml
new file mode 100644
index 000000000..bcfa76d0b
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/manifest-content/pom.xml
@@ -0,0 +1,50 @@
+<!--
+  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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>test</groupId>
+  <artifactId>manifest-content</artifactId>
+  <packaging>war</packaging>
+  <version>1.0-SNAPSHOT</version>
+  <name>Maven War Manifest Content Test</name>
+  <organization>
+    <name>war plugin it</name>
+  </organization>
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-war-plugin</artifactId>
+        <version>@pom.version@</version>
+        <configuration>
+          <failOnMissingWebXml>false</failOnMissingWebXml>
+          <archive>
+            <forced>true</forced>
+            <manifest>
+              <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+              <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
+            </manifest>
+          </archive>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
\ No newline at end of file
diff --git a/Java-base/maven-war-plugin/src/src/it/manifest-content/src/main/webapp/index.jsp b/Java-base/maven-war-plugin/src/src/it/manifest-content/src/main/webapp/index.jsp
new file mode 100644
index 000000000..41db44eef
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/manifest-content/src/main/webapp/index.jsp
@@ -0,0 +1,20 @@
+<%--
+  ~ 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.
+  --%>
+
+<% response.sendRedirect( request.getContextPath() + "/groupSummary.action" ); %>
diff --git a/Java-base/maven-war-plugin/src/src/it/manifest-content/verify.bsh b/Java-base/maven-war-plugin/src/src/it/manifest-content/verify.bsh
new file mode 100644
index 000000000..8980a6f86
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/manifest-content/verify.bsh
@@ -0,0 +1,96 @@
+
+/*
+ * 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.
+ */
+
+import java.io.*;
+import java.util.*;
+import java.util.jar.*;
+import org.codehaus.plexus.util.*;
+
+boolean result = true;
+
+try
+{
+    File target = new File( basedir, "target" );
+    if ( !target.exists() || !target.isDirectory() )
+    {
+        System.err.println( "target file is missing or not a directory." );
+        return false;
+    }
+
+    File artifact = new File( target, "manifest-content-1.0-SNAPSHOT.war" );
+    if ( !artifact.exists() || artifact.isDirectory() )
+    {
+        System.err.println( "artifact file is missing or a directory." );
+        return false;
+    }
+
+    JarFile jar = new JarFile( artifact );
+
+    Attributes manifest = jar.getManifest().getMainAttributes();
+
+    if ( !"Maven War Manifest Content Test".equals( manifest.get( Attributes.Name.SPECIFICATION_TITLE ) ) )
+    {
+        System.err.println( "Incorrect '" + Attributes.Name.SPECIFICATION_TITLE.toString() + "' manifest entry: " +
+            manifest.get( Attributes.Name.SPECIFICATION_TITLE ) );
+        return false;
+    }
+
+    if ( !"1.0".equals( manifest.get( Attributes.Name.SPECIFICATION_VERSION ) ) )
+    {
+        System.err.println( "Incorrect '" + Attributes.Name.SPECIFICATION_VERSION.toString() + "' manifest entry: " +
+            manifest.get( Attributes.Name.SPECIFICATION_VERSION ) );
+        return false;
+    }
+
+    if ( !"war plugin it".equals( manifest.get( Attributes.Name.SPECIFICATION_VENDOR ) ) )
+    {
+        System.err.println( "Incorrect '" + Attributes.Name.SPECIFICATION_VENDOR.toString() + "' manifest entry: " +
+            manifest.get( Attributes.Name.SPECIFICATION_VENDOR ) );
+        return false;
+    }
+
+    if ( !"Maven War Manifest Content Test".equals( manifest.get( Attributes.Name.IMPLEMENTATION_TITLE ) ) )
+    {
+        System.err.println( "Incorrect '" + Attributes.Name.IMPLEMENTATION_TITLE.toString() + "' manifest entry: " +
+            manifest.get( Attributes.Name.IMPLEMENTATION_TITLE ) );
+        return false;
+    }
+
+    if ( !"1.0-SNAPSHOT".equals( manifest.get( Attributes.Name.IMPLEMENTATION_VERSION ) ) )
+    {
+        System.err.println( "Incorrect '" + Attributes.Name.IMPLEMENTATION_VERSION.toString() + "' manifest entry: " +
+            manifest.get( Attributes.Name.IMPLEMENTATION_VERSION ) );
+        return false;
+    }
+
+    if ( !"war plugin it".equals( manifest.get( Attributes.Name.IMPLEMENTATION_VENDOR ) ) )
+    {
+        System.err.println( "Incorrect '" + Attributes.Name.IMPLEMENTATION_VENDOR.toString() + "' manifest entry: " +
+            manifest.get( Attributes.Name.IMPLEMENTATION_VENDOR ) );
+        return false;
+    }
+}
+catch( Throwable e )
+{
+    e.printStackTrace();
+    result = false;
+}
+
+return result;
diff --git a/Java-base/maven-war-plugin/src/src/it/overlay-excludes/invoker.properties b/Java-base/maven-war-plugin/src/src/it/overlay-excludes/invoker.properties
new file mode 100644
index 000000000..3376b9e49
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/overlay-excludes/invoker.properties
@@ -0,0 +1,18 @@
+# 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.
+
+invoker.goals=clean install
diff --git a/Java-base/maven-war-plugin/src/src/it/overlay-excludes/pom.xml b/Java-base/maven-war-plugin/src/src/it/overlay-excludes/pom.xml
new file mode 100644
index 000000000..63c55d499
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/overlay-excludes/pom.xml
@@ -0,0 +1,44 @@
+<?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.
+-->
+<project xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
+         xsi:schemaLocation='http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd'
+         xmlns='http://maven.apache.org/POM/4.0.0'>
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>debug.war</groupId>
+  <artifactId>overlay-excludes</artifactId>
+  <packaging>pom</packaging>
+  <version>1.0-SNAPSHOT</version>
+  <name>test of overlay with exclusions</name>
+  <url>http://maven.apache.org</url>
+  <modules>
+    <module>war-overlay</module>
+    <module>war-exclude-overlay</module>
+  </modules>
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <artifactId>maven-war-plugin</artifactId>
+          <version>@pom.version@</version>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+  </build>
+</project>
diff --git a/Java-base/maven-war-plugin/src/src/it/overlay-excludes/verify.bsh b/Java-base/maven-war-plugin/src/src/it/overlay-excludes/verify.bsh
new file mode 100644
index 000000000..0ba9a0b50
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/overlay-excludes/verify.bsh
@@ -0,0 +1,31 @@
+
+/*
+ * 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.
+ */
+
+import java.io.*;
+import org.codehaus.plexus.util.*;
+
+
+    File testFile = new File( basedir, "war-exclude-overlay/target/war-exclude-overlay-1.0-SNAPSHOT/lib/js/something/else.js");
+    if ( testFile.exists() )
+    {
+        System.err.println( "exclude didn't exclude." );
+        return false;
+    }
+
diff --git a/Java-base/maven-war-plugin/src/src/it/overlay-excludes/war-exclude-overlay/pom.xml b/Java-base/maven-war-plugin/src/src/it/overlay-excludes/war-exclude-overlay/pom.xml
new file mode 100644
index 000000000..c735de79a
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/overlay-excludes/war-exclude-overlay/pom.xml
@@ -0,0 +1,61 @@
+<?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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>debug.war</groupId>
+    <artifactId>overlay-excludes</artifactId>
+    <version>1.0-SNAPSHOT</version>
+  </parent>  
+  <artifactId>war-exclude-overlay</artifactId>
+  <packaging>war</packaging>
+
+  <dependencies> 
+    <!-- War Overlay -->
+    <dependency>
+      <groupId>debug.war</groupId>
+      <artifactId>war-overlay</artifactId>
+      <version>1.0-SNAPSHOT</version>
+      <type>war</type>
+      <scope>runtime</scope>
+    </dependency>
+  </dependencies> 
+  
+  <build>
+    <plugins>      
+      <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-war-plugin</artifactId>
+          <configuration>
+            <overlays>
+              <overlay>
+                <groupId>debug.war</groupId>
+                <artifactId>war-overlay</artifactId>
+                <excludes>
+                  <exclude>lib/js/**</exclude>
+                </excludes>
+              </overlay>
+            </overlays>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/Java-base/maven-war-plugin/src/src/it/overlay-excludes/war-exclude-overlay/src/main/webapp/WEB-INF/web.xml b/Java-base/maven-war-plugin/src/src/it/overlay-excludes/war-exclude-overlay/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 000000000..fc6e240ce
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/overlay-excludes/war-exclude-overlay/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+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.
+-->
+<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
+         version="2.4">
+
+
+</web-app>
diff --git a/Java-base/maven-war-plugin/src/src/it/overlay-excludes/war-overlay/pom.xml b/Java-base/maven-war-plugin/src/src/it/overlay-excludes/war-overlay/pom.xml
new file mode 100644
index 000000000..80f19956a
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/overlay-excludes/war-overlay/pom.xml
@@ -0,0 +1,30 @@
+<?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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>debug.war</groupId>
+    <artifactId>overlay-excludes</artifactId>
+    <version>1.0-SNAPSHOT</version>
+  </parent>
+  <artifactId>war-overlay</artifactId>
+  <packaging>war</packaging>
+</project>
diff --git a/Java-base/maven-war-plugin/src/src/it/overlay-excludes/war-overlay/src/main/webapp/WEB-INF/web.xml b/Java-base/maven-war-plugin/src/src/it/overlay-excludes/war-overlay/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 000000000..357cf72ca
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/overlay-excludes/war-overlay/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+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.
+-->
+<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
+         version="2.4">
+
+</web-app>
diff --git a/Java-base/maven-war-plugin/src/src/it/overlay-excludes/war-overlay/src/main/webapp/lib/js/something/else.js b/Java-base/maven-war-plugin/src/src/it/overlay-excludes/war-overlay/src/main/webapp/lib/js/something/else.js
new file mode 100644
index 000000000..b7bb67336
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/overlay-excludes/war-overlay/src/main/webapp/lib/js/something/else.js
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+/* a javascript file, sort of */
diff --git a/Java-base/maven-war-plugin/src/src/it/overlay-keeps-contextxml/invoker.properties b/Java-base/maven-war-plugin/src/src/it/overlay-keeps-contextxml/invoker.properties
new file mode 100644
index 000000000..3376b9e49
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/overlay-keeps-contextxml/invoker.properties
@@ -0,0 +1,18 @@
+# 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.
+
+invoker.goals=clean install
diff --git a/Java-base/maven-war-plugin/src/src/it/overlay-keeps-contextxml/pom.xml b/Java-base/maven-war-plugin/src/src/it/overlay-keeps-contextxml/pom.xml
new file mode 100644
index 000000000..ade7a13a3
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/overlay-keeps-contextxml/pom.xml
@@ -0,0 +1,44 @@
+<?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.
+-->
+<project xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
+         xsi:schemaLocation='http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd'
+         xmlns='http://maven.apache.org/POM/4.0.0'>
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>debug.war</groupId>
+  <artifactId>overlay-keeps-contextxml</artifactId>
+  <packaging>pom</packaging>
+  <version>1.0-SNAPSHOT</version>
+  <name>test that default overlay keeps META-INF/context.xml</name>
+  <url>http://maven.apache.org</url>
+  <modules>
+    <module>war1-with-contextxml</module>
+    <module>war2-result</module>
+  </modules>
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <artifactId>maven-war-plugin</artifactId>
+          <version>@pom.version@</version>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+  </build>
+</project>
diff --git a/Java-base/maven-war-plugin/src/src/it/overlay-keeps-contextxml/verify.bsh b/Java-base/maven-war-plugin/src/src/it/overlay-keeps-contextxml/verify.bsh
new file mode 100644
index 000000000..f0c99d7ba
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/overlay-keeps-contextxml/verify.bsh
@@ -0,0 +1,31 @@
+
+/*
+ * 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.
+ */
+
+import java.io.*;
+import org.codehaus.plexus.util.*;
+
+
+    File testFile = new File( basedir, "war2-result/target/war2-result-1.0-SNAPSHOT/META-INF/context.xml");
+    if ( !testFile.exists() )
+    {
+        System.err.println( "war1 META-INF/context.xml lost in overlay process" );
+        return false;
+    }
+
diff --git a/Java-base/maven-war-plugin/src/src/it/overlay-keeps-contextxml/war1-with-contextxml/pom.xml b/Java-base/maven-war-plugin/src/src/it/overlay-keeps-contextxml/war1-with-contextxml/pom.xml
new file mode 100644
index 000000000..cfa52bf19
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/overlay-keeps-contextxml/war1-with-contextxml/pom.xml
@@ -0,0 +1,31 @@
+<?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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>debug.war</groupId>
+    <artifactId>overlay-keeps-contextxml</artifactId>
+    <version>1.0-SNAPSHOT</version>
+  </parent>  
+  <artifactId>war1-with-contextxml</artifactId>
+  <packaging>war</packaging>
+
+</project>
diff --git a/Java-base/maven-war-plugin/src/src/it/overlay-keeps-contextxml/war1-with-contextxml/src/main/webapp/META-INF/context.xml b/Java-base/maven-war-plugin/src/src/it/overlay-keeps-contextxml/war1-with-contextxml/src/main/webapp/META-INF/context.xml
new file mode 100644
index 000000000..b14753a76
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/overlay-keeps-contextxml/war1-with-contextxml/src/main/webapp/META-INF/context.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
diff --git a/Java-base/maven-war-plugin/src/src/it/overlay-keeps-contextxml/war1-with-contextxml/src/main/webapp/WEB-INF/web.xml b/Java-base/maven-war-plugin/src/src/it/overlay-keeps-contextxml/war1-with-contextxml/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 000000000..c873e8a02
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/overlay-keeps-contextxml/war1-with-contextxml/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,25 @@
+<?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.
+-->
+<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
+         version="2.4">
+
+</web-app>
diff --git a/Java-base/maven-war-plugin/src/src/it/overlay-keeps-contextxml/war2-result/pom.xml b/Java-base/maven-war-plugin/src/src/it/overlay-keeps-contextxml/war2-result/pom.xml
new file mode 100644
index 000000000..3656cf311
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/overlay-keeps-contextxml/war2-result/pom.xml
@@ -0,0 +1,40 @@
+<?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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>debug.war</groupId>
+    <artifactId>overlay-keeps-contextxml</artifactId>
+    <version>1.0-SNAPSHOT</version>
+  </parent>
+  <artifactId>war2-result</artifactId>
+  <packaging>war</packaging>
+  <dependencies>
+    <!-- War Overlay -->
+    <dependency>
+      <groupId>debug.war</groupId>
+      <artifactId>war1-with-contextxml</artifactId>
+      <version>1.0-SNAPSHOT</version>
+      <type>war</type>
+      <scope>runtime</scope>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/Java-base/maven-war-plugin/src/src/it/overlay-keeps-contextxml/war2-result/src/main/webapp/WEB-INF/web.xml b/Java-base/maven-war-plugin/src/src/it/overlay-keeps-contextxml/war2-result/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 000000000..c873e8a02
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/overlay-keeps-contextxml/war2-result/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,25 @@
+<?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.
+-->
+<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
+         version="2.4">
+
+</web-app>
diff --git a/Java-base/maven-war-plugin/src/src/it/scoped-dependency-same-artifact/invoker.properties b/Java-base/maven-war-plugin/src/src/it/scoped-dependency-same-artifact/invoker.properties
new file mode 100644
index 000000000..c743aa4f3
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/scoped-dependency-same-artifact/invoker.properties
@@ -0,0 +1,18 @@
+# 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.
+
+invoker.goals=clean package
diff --git a/Java-base/maven-war-plugin/src/src/it/scoped-dependency-same-artifact/pom.xml b/Java-base/maven-war-plugin/src/src/it/scoped-dependency-same-artifact/pom.xml
new file mode 100644
index 000000000..8c882baac
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/scoped-dependency-same-artifact/pom.xml
@@ -0,0 +1,53 @@
+<!--
+  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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>test</groupId>
+  <artifactId>scope-depdency-same-artifact</artifactId>
+  <packaging>war</packaging>
+  <version>1.0-SNAPSHOT</version>
+  <name>Maven Simple War Project Test</name>
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-war-plugin</artifactId>
+        <version>@pom.version@</version>
+        <configuration>
+
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <dependencies>
+    <dependency>
+      <groupId>org.codehaus.plexus</groupId>
+      <artifactId>plexus-utils</artifactId>
+      <version>1.4.7</version>
+    </dependency>
+    <dependency>
+      <groupId>org.codehaus.plexus</groupId>
+      <artifactId>plexus-utils</artifactId>
+      <classifier>sources</classifier>
+      <version>1.4.7</version>
+    </dependency>
+  </dependencies>
+</project>
\ No newline at end of file
diff --git a/Java-base/maven-war-plugin/src/src/it/scoped-dependency-same-artifact/src/main/webapp/WEB-INF/web.xml b/Java-base/maven-war-plugin/src/src/it/scoped-dependency-same-artifact/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 000000000..873dd4794
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/scoped-dependency-same-artifact/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,29 @@
+<?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.
+  -->
+
+<web-app xmlns="http://java.sun.com/xml/ns/j2ee" version="2.4"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
+
+  <display-name>Maven Simple War Project Test</display-name>
+
+</web-app>
+
diff --git a/Java-base/maven-war-plugin/src/src/it/scoped-dependency-same-artifact/src/main/webapp/index.jsp b/Java-base/maven-war-plugin/src/src/it/scoped-dependency-same-artifact/src/main/webapp/index.jsp
new file mode 100644
index 000000000..41db44eef
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/scoped-dependency-same-artifact/src/main/webapp/index.jsp
@@ -0,0 +1,20 @@
+<%--
+  ~ 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.
+  --%>
+
+<% response.sendRedirect( request.getContextPath() + "/groupSummary.action" ); %>
diff --git a/Java-base/maven-war-plugin/src/src/it/scoped-dependency-same-artifact/verify.bsh b/Java-base/maven-war-plugin/src/src/it/scoped-dependency-same-artifact/verify.bsh
new file mode 100644
index 000000000..057d78828
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/scoped-dependency-same-artifact/verify.bsh
@@ -0,0 +1,88 @@
+
+/*
+ * 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.
+ */
+
+import java.io.*;
+
+boolean result = true;
+
+try
+{
+    File target = new File( basedir, "target" );
+    if ( !target.exists() || !target.isDirectory() )
+    {
+        System.err.println( "target file is missing or a directory." );
+        return false;
+    }
+
+    File webappDirectory = new File( target, "scope-depdency-same-artifact-1.0-SNAPSHOT" );
+    if ( !webappDirectory.exists() || !webappDirectory.isDirectory() )
+    {
+        System.err.println( "webappDirectory is missing or not a directory." );
+        return false;
+    }
+
+    File webInfFile = new File( webappDirectory, "WEB-INF/web.xml" );
+    if ( !webInfFile.exists() || webInfFile.isDirectory() )
+    {
+        System.err.println( "webInfFile is missing or a directory." );
+        return false;
+    }
+
+    File indexJsp = new File( webappDirectory, "index.jsp" );
+    if ( !indexJsp.exists() || indexJsp.isDirectory() )
+    {
+        System.err.println( "indexJsp is missing or a directory." );
+        return false;
+    }
+
+    File warFile = new File( target, "scope-depdency-same-artifact-1.0-SNAPSHOT.war" );
+    if ( !warFile.exists() || warFile.isDirectory() )
+    {
+        System.err.println( "warFile is missing or a directory." );
+        return false;
+    }
+
+    File libDir = new File( webappDirectory, "WEB-INF/lib" );
+    if ( !libDir.exists() || !libDir.isDirectory() )
+    {
+        System.err.println( "WEB-INF/lib is missing or not a directory." );
+        return false;
+    }
+
+    File plexusUtilsDependency = new File( libDir, "plexus-utils-1.4.7.jar" );
+    if ( !plexusUtilsDependency.exists() || plexusUtilsDependency.isDirectory() )
+    {
+        System.err.println( "plexus-utils-1.4.7.jar is missing or a directory." );
+        return false;
+    }
+    File plexusUtilsSourceDependency = new File( libDir, "plexus-utils-1.4.7-sources.jar" );
+    if ( !plexusUtilsSourceDependency.exists() || plexusUtilsSourceDependency.isDirectory() )
+    {
+        System.err.println( "plexus-utils-1.4.7-sources.jar is missing or a directory." );
+        return false;
+    }
+}
+catch( IOException e )
+{
+    e.printStackTrace();
+    result = false;
+}
+
+return result;
diff --git a/Java-base/maven-war-plugin/src/src/it/settings.xml b/Java-base/maven-war-plugin/src/src/it/settings.xml
new file mode 100644
index 000000000..c8f77f0b7
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/settings.xml
@@ -0,0 +1,55 @@
+<?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.
+-->
+
+<settings>
+  <profiles>
+    <profile>
+      <id>it-repo</id>
+      <activation>
+        <activeByDefault>true</activeByDefault>
+      </activation>
+      <repositories>
+        <repository>
+          <id>local.central</id>
+          <url>@localRepositoryUrl@</url>
+          <releases>
+            <enabled>true</enabled>
+          </releases>
+          <snapshots>
+            <enabled>true</enabled>
+          </snapshots>
+        </repository>
+      </repositories>
+      <pluginRepositories>
+        <pluginRepository>
+          <id>local.central</id>
+          <url>@localRepositoryUrl@</url>
+          <releases>
+            <enabled>true</enabled>
+          </releases>
+          <snapshots>
+            <enabled>true</enabled>
+          </snapshots>
+        </pluginRepository>
+      </pluginRepositories>
+    </profile>
+  </profiles>
+</settings>
diff --git a/Java-base/maven-war-plugin/src/src/it/simple-war-no-webxml/invoker.properties b/Java-base/maven-war-plugin/src/src/it/simple-war-no-webxml/invoker.properties
new file mode 100644
index 000000000..692791cf1
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/simple-war-no-webxml/invoker.properties
@@ -0,0 +1,19 @@
+# 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.
+
+invoker.goals=clean package
+invoker.debug = true
diff --git a/Java-base/maven-war-plugin/src/src/it/simple-war-no-webxml/pom.xml b/Java-base/maven-war-plugin/src/src/it/simple-war-no-webxml/pom.xml
new file mode 100644
index 000000000..31cc0568f
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/simple-war-no-webxml/pom.xml
@@ -0,0 +1,47 @@
+<!--
+  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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>test</groupId>
+  <artifactId>simple-war-no-webxml</artifactId>
+  <packaging>war</packaging>
+  <version>1.0-SNAPSHOT</version>
+  <name>Maven Simple War Project Test</name>
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-war-plugin</artifactId>
+        <version>@pom.version@</version>
+        <configuration>
+          <failOnMissingWebXml>false</failOnMissingWebXml>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <dependencies>
+    <dependency>
+      <groupId>org.codehaus.plexus</groupId>
+      <artifactId>plexus-utils</artifactId>
+      <version>1.4.6</version>
+    </dependency>
+  </dependencies>
+</project>
\ No newline at end of file
diff --git a/Java-base/maven-war-plugin/src/src/it/simple-war-no-webxml/src/main/webapp/index.jsp b/Java-base/maven-war-plugin/src/src/it/simple-war-no-webxml/src/main/webapp/index.jsp
new file mode 100644
index 000000000..41db44eef
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/simple-war-no-webxml/src/main/webapp/index.jsp
@@ -0,0 +1,20 @@
+<%--
+  ~ 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.
+  --%>
+
+<% response.sendRedirect( request.getContextPath() + "/groupSummary.action" ); %>
diff --git a/Java-base/maven-war-plugin/src/src/it/simple-war-no-webxml/verify.bsh b/Java-base/maven-war-plugin/src/src/it/simple-war-no-webxml/verify.bsh
new file mode 100644
index 000000000..b163bbe86
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/simple-war-no-webxml/verify.bsh
@@ -0,0 +1,82 @@
+
+/*
+ * 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.
+ */
+
+import java.io.*;
+
+boolean result = true;
+
+try
+{
+    File target = new File( basedir, "target" );
+    if ( !target.exists() || !target.isDirectory() )
+    {
+        System.err.println( "target file is missing or a directory." );
+        return false;
+    }
+
+    File webappDirectory = new File( target, "simple-war-no-webxml-1.0-SNAPSHOT" );
+    if ( !webappDirectory.exists() || !webappDirectory.isDirectory() )
+    {
+        System.err.println( "webappDirectory is missing or not a directory." );
+        return false;
+    }
+
+    File webInfFile = new File( webappDirectory, "WEB-INF/web.xml" );
+    if ( webInfFile.exists())
+    {
+        System.err.println( "web.xml should not be there." );
+        return false;
+    }
+
+    File indexJsp = new File( webappDirectory, "index.jsp" );
+    if ( !indexJsp.exists() || indexJsp.isDirectory() )
+    {
+        System.err.println( "indexJsp is missing or a directory." );
+        return false;
+    }
+
+    File warFile = new File( target, "simple-war-no-webxml-1.0-SNAPSHOT.war" );
+    if ( !warFile.exists() || warFile.isDirectory() )
+    {
+        System.err.println( "warFile is missing or a directory." );
+        return false;
+    }
+
+    File libDir = new File( webappDirectory, "WEB-INF/lib" );
+    if ( !libDir.exists() || !libDir.isDirectory() )
+    {
+        System.err.println( "WEB-INF/lib is missing or not a directory." );
+        return false;
+    }
+
+    File plexusUtilsDependency = new File( libDir, "plexus-utils-1.4.6.jar" );
+    if ( !plexusUtilsDependency.exists() || plexusUtilsDependency.isDirectory() )
+    {
+        System.err.println( "plexus-utils-1.4.6.jar is missing or a directory." );
+        return false;
+    }
+}
+catch( IOException e )
+{
+    e.printStackTrace();
+    result = false;
+}
+
+return result;
diff --git a/Java-base/maven-war-plugin/src/src/it/simple-war-project/invoker.properties b/Java-base/maven-war-plugin/src/src/it/simple-war-project/invoker.properties
new file mode 100644
index 000000000..c743aa4f3
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/simple-war-project/invoker.properties
@@ -0,0 +1,18 @@
+# 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.
+
+invoker.goals=clean package
diff --git a/Java-base/maven-war-plugin/src/src/it/simple-war-project/pom.xml b/Java-base/maven-war-plugin/src/src/it/simple-war-project/pom.xml
new file mode 100644
index 000000000..a70c4e8a6
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/simple-war-project/pom.xml
@@ -0,0 +1,54 @@
+<!--
+  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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>test</groupId>
+  <artifactId>simple-war-project</artifactId>
+  <packaging>war</packaging>
+  <version>1.0-SNAPSHOT</version>
+  <name>Maven Simple War Project Test</name>
+  <description>maven test it</description>
+
+  <properties>
+    <project.build.outputTimestamp>2020-05-01T12:12:12Z</project.build.outputTimestamp>
+  </properties>
+
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-war-plugin</artifactId>
+        <version>@pom.version@</version>
+        <configuration>
+          <!--webXml>src/main/webapp/WEB-INF/web.xml</webXml-->
+          <filteringDeploymentDescriptors>true</filteringDeploymentDescriptors>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.codehaus.plexus</groupId>
+      <artifactId>plexus-utils</artifactId>
+      <version>1.4.6</version>
+    </dependency>
+  </dependencies>
+</project>
\ No newline at end of file
diff --git a/Java-base/maven-war-plugin/src/src/it/simple-war-project/src/main/webapp/WEB-INF/web.xml b/Java-base/maven-war-plugin/src/src/it/simple-war-project/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 000000000..488bc9739
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/simple-war-project/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,29 @@
+<?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.
+  -->
+
+<web-app xmlns="http://java.sun.com/xml/ns/j2ee" version="2.4"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
+
+  <display-name>${pom.description}</display-name>
+
+</web-app>
+
diff --git a/Java-base/maven-war-plugin/src/src/it/simple-war-project/src/main/webapp/index.jsp b/Java-base/maven-war-plugin/src/src/it/simple-war-project/src/main/webapp/index.jsp
new file mode 100755
index 000000000..4e817f7e9
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/simple-war-project/src/main/webapp/index.jsp
@@ -0,0 +1,20 @@
+<%--
+  ~ 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.
+  --%>
+
+<% response.sendRedirect(  request.getContextPath() + "/groupSummary.action" ); %>
diff --git a/Java-base/maven-war-plugin/src/src/it/simple-war-project/verify.bsh b/Java-base/maven-war-plugin/src/src/it/simple-war-project/verify.bsh
new file mode 100644
index 000000000..7dc3d728a
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/simple-war-project/verify.bsh
@@ -0,0 +1,96 @@
+
+/*
+ * 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.
+ */
+
+import java.io.*;
+
+import org.codehaus.plexus.util.*;
+
+boolean result = true;
+
+try
+{
+    File target = new File( basedir, "target" );
+    if ( !target.exists() || !target.isDirectory() )
+    {
+        System.err.println( "target file is missing or a directory." );
+        return false;
+    }
+
+    File webappDirectory = new File( target, "simple-war-project-1.0-SNAPSHOT" );
+    if ( !webappDirectory.exists() || !webappDirectory.isDirectory() )
+    {
+        System.err.println( "webappDirectory is missing or not a directory." );
+        return false;
+    }
+
+    File webInfFile = new File( webappDirectory, "WEB-INF/web.xml" );
+    if ( !webInfFile.exists() || webInfFile.isDirectory() )
+    {
+        System.err.println( "webInfFile is missing or a directory." );
+        return false;
+    }
+
+
+
+    String paramContent = FileUtils.fileRead( webInfFile, "UTF-8" );
+
+
+    int indexOf = paramContent.indexOf( "<display-name>maven test it</display-name>" );
+    if ( indexOf < 0 )
+    {
+      System.err.println( "web.xml not contains <display-name>maven test it</display-name>" );
+      return false;
+    }
+
+    File indexJsp = new File( webappDirectory, "index.jsp" );
+    if ( !indexJsp.exists() || indexJsp.isDirectory() )
+    {
+        System.err.println( "indexJsp is missing or a directory." );
+        return false;
+    }
+
+    File warFile = new File( target, "simple-war-project-1.0-SNAPSHOT.war" );
+    if ( !warFile.exists() || warFile.isDirectory() )
+    {
+        System.err.println( "warFile is missing or a directory." );
+        return false;
+    }
+
+    File libDir = new File( webappDirectory, "WEB-INF/lib" );
+    if ( !libDir.exists() || !libDir.isDirectory() )
+    {
+        System.err.println( "WEB-INF/lib is missing or not a directory." );
+        return false;
+    }
+
+    File plexusUtilsDependency = new File( libDir, "plexus-utils-1.4.6.jar" );
+    if ( !plexusUtilsDependency.exists() || plexusUtilsDependency.isDirectory() )
+    {
+        System.err.println( "plexus-utils-1.4.6.jar is missing or a directory." );
+        return false;
+    }
+}
+catch( IOException e )
+{
+    e.printStackTrace();
+    result = false;
+}
+
+return result;
diff --git a/Java-base/maven-war-plugin/src/src/it/web-resources-filtering-delimiter/parent/pom.xml b/Java-base/maven-war-plugin/src/src/it/web-resources-filtering-delimiter/parent/pom.xml
new file mode 100644
index 000000000..cee6b8395
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/web-resources-filtering-delimiter/parent/pom.xml
@@ -0,0 +1,62 @@
+<?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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+  <modelVersion>4.0.0</modelVersion>
+
+  <name>Company Parent</name>
+  <description>Parent that handles dependencyManagement</description>
+
+  <groupId>com.edb.finance.example</groupId>
+  <artifactId>example-parent</artifactId> 
+  <version>1.0.0-SNAPSHOT</version>
+  <packaging>pom</packaging>
+  <inceptionYear>2008</inceptionYear>
+
+  <developers>
+    <developer>
+      <id>1</id>
+      <name>Valeriy Molyakov</name>
+      <email>valeriy.molyakov@infopulse.com.ua</email>
+      <organization>EDB Business Partner</organization>
+      <organizationUrl>http://www.edb.com</organizationUrl>
+      <roles>
+        <role>developer</role>
+      </roles>
+      <timezone>+2</timezone>
+    </developer>
+  </developers>
+
+  <distributionManagement>
+    <site>
+      <id>sample.website</id>
+      <url>${website.url}/${project.name}</url>
+    </site>
+  </distributionManagement>
+
+
+  <properties>
+    <jdbc.url>jdbc:oracle:thin:@localhost:1521:orcl</jdbc.url>
+    <website.url>scp://www.yourcompany.com/www/docs/project</website.url>
+  </properties>
+
+</project>
diff --git a/Java-base/maven-war-plugin/src/src/it/web-resources-filtering-delimiter/pom.xml b/Java-base/maven-war-plugin/src/src/it/web-resources-filtering-delimiter/pom.xml
new file mode 100644
index 000000000..84391162f
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/web-resources-filtering-delimiter/pom.xml
@@ -0,0 +1,44 @@
+<?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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>com.edb.finance.example</groupId>
+    <artifactId>example-parent</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <relativePath>parent/pom.xml</relativePath>
+  </parent>
+
+
+  <artifactId>example</artifactId>
+  <packaging>pom</packaging>
+  
+  <name>Example Maven Multi-module project For Filtering with Delimiters</name>
+  <url>http://maven.apache.org</url>
+
+  <modules>
+    <module>parent</module>
+    <module>web</module>
+  </modules>
+
+
+</project>
diff --git a/Java-base/maven-war-plugin/src/src/it/web-resources-filtering-delimiter/verify.bsh b/Java-base/maven-war-plugin/src/src/it/web-resources-filtering-delimiter/verify.bsh
new file mode 100644
index 000000000..dd86ecd4b
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/web-resources-filtering-delimiter/verify.bsh
@@ -0,0 +1,108 @@
+
+/*
+ * 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.
+ */
+
+import java.io.*;
+
+import org.codehaus.plexus.util.*;
+
+boolean result = true;
+
+try
+{
+    // Load and check jetty-env.xml
+
+    File target = new File( basedir, "web/target/example-web/WEB-INF" );
+    if ( !target.exists() || !target.isDirectory() )
+    {
+        System.err.println( "web/target/example-web/WEB-INF is missing or is not a directory." );
+        return false;
+    }
+
+    File jettyEnv = new File( target, "jetty-env.xml" );
+    if ( !jettyEnv.exists() || jettyEnv.isDirectory() )
+    {
+        System.err.println( "jetty-env.xml is missing or is a directory." );
+        return false;
+    }
+
+
+    FileInputStream fis = new FileInputStream ( jettyEnv );
+    String paramContent = IOUtil.toString ( fis, "UTF-8" );
+
+    System.out.println( "content='" + paramContent + "'" );
+
+
+    int indexOf = paramContent.indexOf( "Characters that should be encoded in UTF-8: åäö" );
+    if ( indexOf < 0 )
+    {
+      System.err.println( "Non-ascii characters changed encoding during filtering" );
+      return false;
+    }
+
+    indexOf = paramContent.indexOf( "<Set name=\"URL\">jdbc:oracle:thin:@localhost:1521:orcl</Set>" );
+    if ( indexOf < 0 )
+    {
+      System.err.println( "jdbc.url not filtered correctly" );
+      return false;
+    }
+
+    indexOf = paramContent.indexOf( "<Set name=\"password\">@@jdbc.password@@</Set>" );
+    if ( indexOf < 0 )
+    {
+      System.err.println( "jdbc.password has been filtered" );
+      return false;
+    }
+
+    // Load and check my.properties
+
+    target = new File( basedir, "web/target/example-web/WEB-INF/classes" );
+    if ( !target.exists() || !target.isDirectory() )
+    {
+        System.err.println( "web/target/example-web/WEB-INF/classes is missing or is not a directory." );
+        return false;
+    }
+
+    File myProperties = new File( target, "my.properties" );
+    if ( !myProperties.exists() || myProperties.isDirectory() )
+    {
+        System.err.println( "my.properties is missing or is a directory." );
+        return false;
+    }
+
+    Properties properties = new Properties();
+    FileInputStream fis = new FileInputStream( myProperties );
+    properties.load( fis );
+    fis.close();
+
+    String property = properties.get( "my.property" );
+    System.out.println( "my.property='" + property + "'" );
+    if ( !"Characters that should be encoded in ISO-8859-1: åäö".equals( property ) )
+    {
+        System.err.println( "Non-ascii characters has wrong encoding after filtering" );
+        return false;
+    }
+}
+catch( IOException e )
+{
+    e.printStackTrace();
+    result = false;
+}
+
+return result;
diff --git a/Java-base/maven-war-plugin/src/src/it/web-resources-filtering-delimiter/web/pom.xml b/Java-base/maven-war-plugin/src/src/it/web-resources-filtering-delimiter/web/pom.xml
new file mode 100644
index 000000000..531d27909
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/web-resources-filtering-delimiter/web/pom.xml
@@ -0,0 +1,72 @@
+<?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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>com.edb.finance.example</groupId>
+    <artifactId>example-parent</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <relativePath>../parent/pom.xml</relativePath>
+  </parent>
+
+
+  <artifactId>example-web</artifactId>
+  <packaging>war</packaging>
+  
+  <name>example-web Maven Webapp</name>
+  <url>http://maven.apache.org</url>
+
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.1</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <finalName>example-web</finalName>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-war-plugin</artifactId>
+        <version>@pom.version@</version>
+        <configuration>
+          <escapeString>\</escapeString>
+          <supportMultiLineFiltering>true</supportMultiLineFiltering>
+          <webResources>
+            <resource>
+              <directory>${basedir}/src/main/webresources</directory>
+              <filtering>true</filtering>
+            </resource>
+          </webResources>
+          <resourceEncoding>ISO-8859-1</resourceEncoding>
+          <delimiters>
+            <delimiter>@@*@@</delimiter>
+          </delimiters>
+          <useDefaultDelimiters>false</useDefaultDelimiters>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/Java-base/maven-war-plugin/src/src/it/web-resources-filtering-delimiter/web/src/main/webapp/WEB-INF/web.xml b/Java-base/maven-war-plugin/src/src/it/web-resources-filtering-delimiter/web/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 000000000..36c5645fb
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/web-resources-filtering-delimiter/web/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,26 @@
+<?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.
+-->
+<!DOCTYPE web-app PUBLIC
+ "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+ "http://java.sun.com/dtd/web-app_2_3.dtd" >
+
+<web-app>
+  <display-name>Archetype Created Web Application</display-name>
+</web-app>
diff --git a/Java-base/maven-war-plugin/src/src/it/web-resources-filtering-delimiter/web/src/main/webapp/index.jsp b/Java-base/maven-war-plugin/src/src/it/web-resources-filtering-delimiter/web/src/main/webapp/index.jsp
new file mode 100755
index 000000000..1f294feb8
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/web-resources-filtering-delimiter/web/src/main/webapp/index.jsp
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+<html>
+<body>
+<h2>Hello World!</h2>
+</body>
+</html>
diff --git a/Java-base/maven-war-plugin/src/src/it/web-resources-filtering-delimiter/web/src/main/webresources/WEB-INF/classes/my.properties b/Java-base/maven-war-plugin/src/src/it/web-resources-filtering-delimiter/web/src/main/webresources/WEB-INF/classes/my.properties
new file mode 100644
index 000000000..d07696737
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/web-resources-filtering-delimiter/web/src/main/webresources/WEB-INF/classes/my.properties
@@ -0,0 +1,18 @@
+# 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.
+
+my.property=Characters that should be encoded in ISO-8859-1: åäö
\ No newline at end of file
diff --git a/Java-base/maven-war-plugin/src/src/it/web-resources-filtering-delimiter/web/src/main/webresources/WEB-INF/jetty-env.xml b/Java-base/maven-war-plugin/src/src/it/web-resources-filtering-delimiter/web/src/main/webresources/WEB-INF/jetty-env.xml
new file mode 100644
index 000000000..68ffb6646
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/web-resources-filtering-delimiter/web/src/main/webresources/WEB-INF/jetty-env.xml
@@ -0,0 +1,40 @@
+<?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.
+-->
+<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN"
+        "http://jetty.mortbay.org/configure.dtd">
+<Configure class="org.mortbay.jetty.webapp.WebAppContext">
+  <!--
+    This file is encoded in UTF-8 and should be so after filtering, since it
+    specifies an encoding in the xml header. So the following characters should
+    remain unaltered after filtering even though the encoding for filtering is
+    set to ISO-8859-1:
+    Characters that should be encoded in UTF-8: åäö
+  -->
+  <New id="MyDS" class="org.mortbay.jetty.plus.naming.Resource">
+    <Arg>jdbc/EventdialogDS</Arg>
+    <Arg>
+      <New class="oracle.jdbc.pool.OracleConnectionPoolDataSource">
+        <Set name="URL">@@jdbc.url@@</Set>
+        <Set name="user">@@jdbc.user@@</Set>
+        <Set name="password">\@@jdbc.password@@</Set>
+      </New>
+    </Arg>
+  </New>
+</Configure>
diff --git a/Java-base/maven-war-plugin/src/src/it/web-resources-filtering/parent/pom.xml b/Java-base/maven-war-plugin/src/src/it/web-resources-filtering/parent/pom.xml
new file mode 100644
index 000000000..cee6b8395
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/web-resources-filtering/parent/pom.xml
@@ -0,0 +1,62 @@
+<?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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+  <modelVersion>4.0.0</modelVersion>
+
+  <name>Company Parent</name>
+  <description>Parent that handles dependencyManagement</description>
+
+  <groupId>com.edb.finance.example</groupId>
+  <artifactId>example-parent</artifactId> 
+  <version>1.0.0-SNAPSHOT</version>
+  <packaging>pom</packaging>
+  <inceptionYear>2008</inceptionYear>
+
+  <developers>
+    <developer>
+      <id>1</id>
+      <name>Valeriy Molyakov</name>
+      <email>valeriy.molyakov@infopulse.com.ua</email>
+      <organization>EDB Business Partner</organization>
+      <organizationUrl>http://www.edb.com</organizationUrl>
+      <roles>
+        <role>developer</role>
+      </roles>
+      <timezone>+2</timezone>
+    </developer>
+  </developers>
+
+  <distributionManagement>
+    <site>
+      <id>sample.website</id>
+      <url>${website.url}/${project.name}</url>
+    </site>
+  </distributionManagement>
+
+
+  <properties>
+    <jdbc.url>jdbc:oracle:thin:@localhost:1521:orcl</jdbc.url>
+    <website.url>scp://www.yourcompany.com/www/docs/project</website.url>
+  </properties>
+
+</project>
diff --git a/Java-base/maven-war-plugin/src/src/it/web-resources-filtering/pom.xml b/Java-base/maven-war-plugin/src/src/it/web-resources-filtering/pom.xml
new file mode 100644
index 000000000..8412bae76
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/web-resources-filtering/pom.xml
@@ -0,0 +1,44 @@
+<?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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>com.edb.finance.example</groupId>
+    <artifactId>example-parent</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <relativePath>parent/pom.xml</relativePath>
+  </parent>
+
+
+  <artifactId>example</artifactId>
+  <packaging>pom</packaging>
+  
+  <name>Example Maven Multi-module project</name>
+  <url>http://maven.apache.org</url>
+
+  <modules>
+    <module>parent</module>
+    <module>web</module>
+  </modules>
+
+
+</project>
diff --git a/Java-base/maven-war-plugin/src/src/it/web-resources-filtering/verify.bsh b/Java-base/maven-war-plugin/src/src/it/web-resources-filtering/verify.bsh
new file mode 100644
index 000000000..6ea7d17be
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/web-resources-filtering/verify.bsh
@@ -0,0 +1,115 @@
+
+/*
+ * 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.
+ */
+
+import java.io.*;
+
+import org.codehaus.plexus.util.*;
+
+boolean result = true;
+
+try
+{
+    // Load and check jetty-env.xml
+
+    File target = new File( basedir, "web/target/example-web/WEB-INF" );
+    if ( !target.exists() || !target.isDirectory() )
+    {
+        System.err.println( "web/target/example-web/WEB-INF is missing or is not a directory." );
+        return false;
+    }
+
+    File jettyEnv = new File( target, "jetty-env.xml" );
+    if ( !jettyEnv.exists() || jettyEnv.isDirectory() )
+    {
+        System.err.println( "jetty-env.xml is missing or is a directory." );
+        return false;
+    }
+
+
+    FileInputStream fis = new FileInputStream ( jettyEnv );
+    String paramContent = IOUtil.toString ( fis, "UTF-8" );
+
+    System.out.println( "content='" + paramContent + "'" );
+
+
+    int indexOf = paramContent.indexOf( "Characters that should be encoded in UTF-8: åäö" );
+    if ( indexOf < 0 )
+    {
+      System.err.println( "Non-ascii characters changed encoding during filtering" );
+      return false;
+    }
+
+    indexOf = paramContent.indexOf( "Author id: 1" );
+    if ( indexOf < 0 )
+    {
+      System.err.println( "project.developers[0].id not filtered correctly" );
+      return false;
+    }
+
+    indexOf = paramContent.indexOf( "<Set name=\"URL\">jdbc:oracle:thin:@localhost:1521:orcl</Set>" );
+    if ( indexOf < 0 )
+    {
+      System.err.println( "jdbc.url not filtered correctly" );
+      return false;
+    }
+
+    indexOf = paramContent.indexOf( "<Set name=\"password\">${jdbc.password}</Set>" );
+    if ( indexOf < 0 )
+    {
+      System.err.println( "jdbc.password has been filtered" );
+      return false;
+    }
+
+    // Load and check my.properties
+
+    target = new File( basedir, "web/target/example-web/WEB-INF/classes" );
+    if ( !target.exists() || !target.isDirectory() )
+    {
+        System.err.println( "web/target/example-web/WEB-INF/classes is missing or is not a directory." );
+        return false;
+    }
+
+    File myProperties = new File( target, "my.properties" );
+    if ( !myProperties.exists() || myProperties.isDirectory() )
+    {
+        System.err.println( "my.properties is missing or is a directory." );
+        return false;
+    }
+
+    Properties properties = new Properties();
+    FileInputStream fis = new FileInputStream( myProperties );
+    properties.load( fis );
+    fis.close();
+
+    String property = properties.get( "my.property" );
+    System.out.println( "my.property='" + property + "'" );
+    if ( !"Characters that should be encoded in ISO-8859-1: åäö".equals( property ) )
+    {
+        System.err.println( "Non-ascii characters has wrong encoding after filtering" );
+        return false;
+    }
+}
+catch( IOException e )
+{
+    e.printStackTrace();
+    result = false;
+}
+
+return result;
diff --git a/Java-base/maven-war-plugin/src/src/it/web-resources-filtering/web/pom.xml b/Java-base/maven-war-plugin/src/src/it/web-resources-filtering/web/pom.xml
new file mode 100644
index 000000000..071888abc
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/web-resources-filtering/web/pom.xml
@@ -0,0 +1,68 @@
+<?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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>com.edb.finance.example</groupId>
+    <artifactId>example-parent</artifactId>
+    <version>1.0.0-SNAPSHOT</version>
+    <relativePath>../parent/pom.xml</relativePath>
+  </parent>
+
+
+  <artifactId>example-web</artifactId>
+  <packaging>war</packaging>
+  
+  <name>example-web Maven Webapp</name>
+  <url>http://maven.apache.org</url>
+
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>3.8.1</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <finalName>example-web</finalName>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-war-plugin</artifactId>
+        <version>@pom.version@</version>
+        <configuration>
+          <escapeString>\</escapeString>
+          <supportMultiLineFiltering>true</supportMultiLineFiltering>
+          <webResources>
+            <resource>
+              <directory>${basedir}/src/main/webresources</directory>
+              <filtering>true</filtering>
+            </resource>
+          </webResources>
+          <resourceEncoding>ISO-8859-1</resourceEncoding>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/Java-base/maven-war-plugin/src/src/it/web-resources-filtering/web/src/main/webapp/WEB-INF/web.xml b/Java-base/maven-war-plugin/src/src/it/web-resources-filtering/web/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 000000000..36c5645fb
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/web-resources-filtering/web/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,26 @@
+<?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.
+-->
+<!DOCTYPE web-app PUBLIC
+ "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+ "http://java.sun.com/dtd/web-app_2_3.dtd" >
+
+<web-app>
+  <display-name>Archetype Created Web Application</display-name>
+</web-app>
diff --git a/Java-base/maven-war-plugin/src/src/it/web-resources-filtering/web/src/main/webapp/index.jsp b/Java-base/maven-war-plugin/src/src/it/web-resources-filtering/web/src/main/webapp/index.jsp
new file mode 100755
index 000000000..1f294feb8
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/web-resources-filtering/web/src/main/webapp/index.jsp
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+<html>
+<body>
+<h2>Hello World!</h2>
+</body>
+</html>
diff --git a/Java-base/maven-war-plugin/src/src/it/web-resources-filtering/web/src/main/webresources/WEB-INF/classes/my.properties b/Java-base/maven-war-plugin/src/src/it/web-resources-filtering/web/src/main/webresources/WEB-INF/classes/my.properties
new file mode 100644
index 000000000..d07696737
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/web-resources-filtering/web/src/main/webresources/WEB-INF/classes/my.properties
@@ -0,0 +1,18 @@
+# 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.
+
+my.property=Characters that should be encoded in ISO-8859-1: åäö
\ No newline at end of file
diff --git a/Java-base/maven-war-plugin/src/src/it/web-resources-filtering/web/src/main/webresources/WEB-INF/jetty-env.xml b/Java-base/maven-war-plugin/src/src/it/web-resources-filtering/web/src/main/webresources/WEB-INF/jetty-env.xml
new file mode 100644
index 000000000..20d9ebd86
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/it/web-resources-filtering/web/src/main/webresources/WEB-INF/jetty-env.xml
@@ -0,0 +1,44 @@
+<?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.
+-->
+<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN"
+        "http://jetty.mortbay.org/configure.dtd">
+<Configure class="org.mortbay.jetty.webapp.WebAppContext">
+  <!--
+    This file is encoded in UTF-8 and should be so after filtering, since it
+    specifies an encoding in the xml header. So the following characters should
+    remain unaltered after filtering even though the encoding for filtering is
+    set to ISO-8859-1:
+    Characters that should be encoded in UTF-8: åäö
+  -->
+  <!--
+    Filter a complex expression:
+    Author id: ${project.developers[0].id}
+  -->
+  <New id="MyDS" class="org.mortbay.jetty.plus.naming.Resource">
+    <Arg>jdbc/EventdialogDS</Arg>
+    <Arg>
+      <New class="oracle.jdbc.pool.OracleConnectionPoolDataSource">
+        <Set name="URL">${jdbc.url}</Set>
+        <Set name="user">${jdbc.user}</Set>
+        <Set name="password">\${jdbc.password}</Set>
+      </New>
+    </Arg>
+  </New>
+</Configure>
diff --git a/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/AbstractWarMojo.java b/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/AbstractWarMojo.java
new file mode 100644
index 000000000..5595124ca
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/AbstractWarMojo.java
@@ -0,0 +1,1152 @@
+package org.apache.maven.plugins.war;
+
+/*
+ * 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.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+
+import org.apache.maven.archiver.MavenArchiveConfiguration;
+import org.apache.maven.artifact.factory.ArtifactFactory;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.model.Resource;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugin.logging.Log;
+import org.apache.maven.plugins.annotations.Component;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.plugins.war.overlay.OverlayManager;
+import org.apache.maven.plugins.war.packaging.CopyUserManifestTask;
+import org.apache.maven.plugins.war.packaging.OverlayPackagingTask;
+import org.apache.maven.plugins.war.packaging.WarPackagingContext;
+import org.apache.maven.plugins.war.packaging.WarPackagingTask;
+import org.apache.maven.plugins.war.packaging.WarProjectPackagingTask;
+import org.apache.maven.plugins.war.util.WebappStructure;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.shared.filtering.MavenFileFilter;
+import org.apache.maven.shared.filtering.MavenFilteringException;
+import org.apache.maven.shared.filtering.MavenResourcesExecution;
+import org.apache.maven.shared.filtering.MavenResourcesFiltering;
+import org.apache.maven.shared.utils.StringUtils;
+import org.apache.maven.shared.utils.io.FileUtils;
+import org.codehaus.plexus.archiver.Archiver;
+import org.codehaus.plexus.archiver.jar.JarArchiver;
+import org.codehaus.plexus.archiver.manager.ArchiverManager;
+
+/**
+ * Contains common jobs for WAR mojos.
+ */
+public abstract class AbstractWarMojo
+    extends AbstractMojo
+{
+    private static final String META_INF = "META-INF";
+
+    private static final String WEB_INF = "WEB-INF";
+    /**
+     * Whether or not to fail the build if the <code>web.xml</code> file is missing. Set to <code>false</code> if you
+     * want your WAR built without a <code>web.xml</code> file. This may be useful if you are building an overlay that
+     * has no web.xml file.
+     * <p>
+     * Starting with <b>3.1.0</b>, this property defaults to <code>false</code> if the project depends on the Servlet
+     * 3.0 API or newer.
+     *
+     * @since 2.1-alpha-2
+     */
+    @Parameter
+    protected Boolean failOnMissingWebXml;
+
+    /**
+     * The Maven project.
+     */
+    @Parameter( defaultValue = "${project}", readonly = true, required = true )
+    private MavenProject project;
+
+    /**
+     * The directory containing compiled classes.
+     */
+    @Parameter( defaultValue = "${project.build.outputDirectory}", required = true, readonly = true )
+    private File classesDirectory;
+
+    /**
+     * Whether a JAR file will be created for the classes in the webapp. Using this optional configuration parameter
+     * will make the compiled classes to be archived into a JAR file in <code>/WEB-INF/lib/</code> and the classes
+     * directory will then be excluded from the webapp <code>/WEB-INF/classes/</code>.
+     *
+     * @since 2.0.1
+     */
+    @Parameter( defaultValue = "false" )
+    private boolean archiveClasses;
+
+    /**
+     * The encoding to use when copying filtered web resources.
+     *
+     * @since 2.3
+     */
+    @Parameter( defaultValue = "${project.build.sourceEncoding}" )
+    private String resourceEncoding;
+
+    /**
+     * The JAR archiver needed for archiving the classes directory into a JAR file under WEB-INF/lib.
+     */
+    @Component( role = Archiver.class, hint = "jar" )
+    private JarArchiver jarArchiver;
+
+    /**
+     * The directory where the webapp is built.
+     */
+    @Parameter( defaultValue = "${project.build.directory}/${project.build.finalName}", required = true )
+    private File webappDirectory;
+
+    /**
+     * Single directory for extra files to include in the WAR. This is where you place your JSP files.
+     */
+    @Parameter( defaultValue = "${basedir}/src/main/webapp", required = true )
+    private File warSourceDirectory;
+
+    /**
+     * The list of webResources we want to transfer.
+     */
+    @Parameter
+    private Resource[] webResources;
+
+    /**
+     * Filters (property files) to include during the interpolation of the pom.xml.
+     */
+    @Parameter
+    private List<String> filters;
+
+    /**
+     * <p>
+     * Set of delimiters for expressions to filter within the resources. These delimiters are specified in the form
+     * 'beginToken*endToken'. If no '*' is given, the delimiter is assumed to be the same for start and end.
+     * </p>
+     * <p>
+     * So, the default filtering delimiters might be specified as:
+     * </p>
+     * 
+     * <pre>
+     * &lt;delimiters&gt;
+     *   &lt;delimiter&gt;${*}&lt;/delimiter&gt;
+     *   &lt;delimiter&gt;@&lt;/delimiter&gt;
+     * &lt;/delimiters&gt;
+     * </pre>
+     * <p>
+     * Since the '@' delimiter is the same on both ends, we don't need to specify '@*@' (though we can).
+     * </p>
+     *
+     * @since 3.0.0
+     */
+    @Parameter
+    private LinkedHashSet<String> delimiters;
+
+    /**
+     * Use default delimiters in addition to custom delimiters, if any.
+     *
+     * @since 3.0.0
+     */
+    @Parameter( defaultValue = "true" )
+    private boolean useDefaultDelimiters;
+
+    /**
+     * The path to the web.xml file to use.
+     */
+    @Parameter
+    private File webXml;
+
+    /**
+     * The path to a configuration file for the servlet container. Note that the file name may be different for
+     * different servlet containers. Apache Tomcat uses a configuration file named context.xml. The file will be copied
+     * to the META-INF directory.
+     */
+    @Parameter
+    private File containerConfigXML;
+
+    /**
+     * Directory to unpack dependent WARs into if needed.
+     */
+    @Parameter( defaultValue = "${project.build.directory}/war/work", required = true )
+    private File workDirectory;
+
+    /**
+     * The file name mapping to use when copying libraries and TLDs. If no file mapping is set (default) the files are
+     * copied with their standard names.
+     *
+     * @since 2.1-alpha-1
+     */
+    @Parameter
+    private String outputFileNameMapping;
+
+    /**
+     */
+    @Component( role = ArtifactFactory.class )
+    private ArtifactFactory artifactFactory;
+
+    /**
+     * To look up Archiver/UnArchiver implementations.
+     */
+    @Component( role = ArchiverManager.class )
+    private ArchiverManager archiverManager;
+
+    /**
+     */
+    @Component( role = MavenFileFilter.class, hint = "default" )
+    private MavenFileFilter mavenFileFilter;
+
+    /**
+     */
+    @Component( role = MavenResourcesFiltering.class, hint = "default" )
+    private MavenResourcesFiltering mavenResourcesFiltering;
+
+    /**
+     * The comma separated list of tokens to include when copying the content of the warSourceDirectory.
+     */
+    @Parameter( defaultValue = "**" )
+    private String warSourceIncludes;
+
+    /**
+     * The comma separated list of tokens to exclude when copying the content of the warSourceDirectory.
+     */
+    @Parameter
+    private String warSourceExcludes;
+
+    /**
+     * The comma separated list of tokens to include when doing a WAR overlay. Default is 
+     * {@link org.apache.maven.plugins.war.Overlay#DEFAULT_INCLUDES}
+     *
+     */
+    @Parameter
+    private String dependentWarIncludes = StringUtils.join( Overlay.DEFAULT_INCLUDES, "," );
+
+    /**
+     * The comma separated list of tokens to exclude when doing a WAR overlay. Default is 
+     * {@link org.apache.maven.plugins.war.Overlay#DEFAULT_EXCLUDES}
+     *
+     */
+    @Parameter
+    private String dependentWarExcludes = StringUtils.join( Overlay.DEFAULT_EXCLUDES, "," );
+
+    /**
+     * The overlays to apply. Each &lt;overlay&gt; element may contain:
+     * <ul>
+     * <li>id (defaults to <tt>currentBuild</tt>)</li>
+     * <li>groupId (if this and artifactId are null, then the current project is treated as its own overlay)</li>
+     * <li>artifactId (see above)</li>
+     * <li>classifier</li>
+     * <li>type</li>
+     * <li>includes (a list of string patterns)</li>
+     * <li>excludes (a list of string patterns)</li>
+     * <li>filtered (defaults to false)</li>
+     * <li>skip (defaults to false)</li>
+     * <li>targetPath (defaults to root of webapp structure)</li>
+     * </ul>
+     *
+     * @since 2.1-alpha-1
+     */
+    @Parameter
+    private List<Overlay> overlays = new ArrayList<>();
+
+    /**
+     * A list of file extensions that should not be filtered. <b>Will be used when filtering webResources and
+     * overlays.</b>
+     *
+     * @since 2.1-alpha-2
+     */
+    @Parameter
+    private List<String> nonFilteredFileExtensions;
+
+    /**
+     * @since 2.1-alpha-2
+     */
+    @Parameter( defaultValue = "${session}", readonly = true, required = true )
+    private MavenSession session;
+
+    /**
+     * To filter deployment descriptors. <b>Disabled by default.</b>
+     *
+     * @since 2.1-alpha-2
+     */
+    @Parameter( defaultValue = "false" )
+    private boolean filteringDeploymentDescriptors;
+
+    /**
+     * To escape interpolated values with Windows path <code>c:\foo\bar</code> will be replaced with
+     * <code>c:\\foo\\bar</code>.
+     *
+     * @since 2.1-alpha-2
+     */
+    @Parameter( defaultValue = "false" )
+    private boolean escapedBackslashesInFilePath;
+
+    /**
+     * Expression preceded with this String won't be interpolated. <code>\${foo}</code> will be replaced with
+     * <code>${foo}</code>.
+     *
+     * @since 2.1-beta-1
+     */
+    @Parameter
+    protected String escapeString;
+
+    /**
+     * Indicates if zip archives (jar,zip etc) being added to the war should be compressed again. Compressing again can
+     * result in smaller archive size, but gives noticeably longer execution time.
+     *
+     * @since 2.3
+     */
+    @Parameter( defaultValue = "true" )
+    private boolean recompressZippedFiles;
+
+    /**
+     * @since 2.4
+     */
+    @Parameter( defaultValue = "false" )
+    private boolean includeEmptyDirectories;
+
+    /**
+     * Stop searching endToken at the end of line
+     * 
+     * @since 2.4
+     */
+    @Parameter( defaultValue = "false" )
+    private boolean supportMultiLineFiltering;
+
+    /**
+     * use jvmChmod rather that cli chmod and forking process
+     * 
+     * @since 2.4
+     */
+    @Parameter( defaultValue = "true" )
+    private boolean useJvmChmod;
+
+    /**
+     * The archive configuration to use. See <a href="http://maven.apache.org/shared/maven-archiver/index.html">Maven
+     * Archiver Reference</a>.
+     */
+    @Parameter
+    private MavenArchiveConfiguration archive = new MavenArchiveConfiguration();
+
+    /**
+     * Timestamp for reproducible output archive entries, either formatted as ISO 8601
+     * <code>yyyy-MM-dd'T'HH:mm:ssXXX</code> or as an int representing seconds since the epoch (like
+     * <a href="https://reproducible-builds.org/docs/source-date-epoch/">SOURCE_DATE_EPOCH</a>).
+     *
+     * @since 3.3.0
+     */
+    @Parameter( defaultValue = "${project.build.outputTimestamp}" )
+    protected String outputTimestamp;
+
+    private final Overlay currentProjectOverlay = Overlay.createInstance();
+
+    /**
+     * @return The current overlay.
+     */
+    public Overlay getCurrentProjectOverlay()
+    {
+        return currentProjectOverlay;
+    }
+
+    /**
+     * Returns a string array of the excludes to be used when copying the content of the WAR source directory.
+     *
+     * @return an array of tokens to exclude
+     */
+    protected String[] getExcludes()
+    {
+        List<String> excludeList = new ArrayList<>();
+        if ( StringUtils.isNotEmpty( warSourceExcludes ) )
+        {
+            excludeList.addAll( Arrays.asList( StringUtils.split( warSourceExcludes, "," ) ) );
+        }
+
+        // if webXML is specified, omit the one in the source directory
+        if ( webXml != null && StringUtils.isNotEmpty( webXml.getName() ) )
+        {
+            excludeList.add( "**/" + WEB_INF + "/web.xml" );
+        }
+
+        // if contextXML is specified, omit the one in the source directory
+        if ( containerConfigXML != null && StringUtils.isNotEmpty( containerConfigXML.getName() ) )
+        {
+            excludeList.add( "**/" + META_INF + "/" + containerConfigXML.getName() );
+        }
+
+        return excludeList.toArray( new String[excludeList.size()] );
+    }
+
+    /**
+     * Returns a string array of the includes to be used when assembling/copying the WAR.
+     *
+     * @return an array of tokens to include
+     */
+    protected String[] getIncludes()
+    {
+        return StringUtils.split( StringUtils.defaultString( warSourceIncludes ), "," );
+    }
+
+    /**
+     * Returns a string array of the excludes to be used when adding dependent WAR as an overlay onto this WAR.
+     *
+     * @return an array of tokens to exclude
+     */
+    protected String[] getDependentWarExcludes()
+    {
+        return StringUtils.split( StringUtils.defaultString( dependentWarExcludes ), "," );
+    }
+
+    /**
+     * Returns a string array of the includes to be used when adding dependent WARs as an overlay onto this WAR.
+     *
+     * @return an array of tokens to include
+     */
+    protected String[] getDependentWarIncludes()
+    {
+        return StringUtils.split( StringUtils.defaultString( dependentWarIncludes ), "," );
+    }
+
+    /**
+     * @param webapplicationDirectory The web application directory.
+     * @throws MojoExecutionException In case of failure.
+     * @throws MojoFailureException In case of failure.
+     */
+    public void buildExplodedWebapp( File webapplicationDirectory )
+        throws MojoExecutionException, MojoFailureException
+    {
+        webapplicationDirectory.mkdirs();
+
+        try
+        {
+            buildWebapp( project, webapplicationDirectory );
+        }
+        catch ( IOException e )
+        {
+            throw new MojoExecutionException( "Could not build webapp", e );
+        }
+    }
+
+    /**
+     * Builds the webapp for the specified project with the new packaging task thingy.
+     * Classes, libraries and tld files are copied to the <tt>webappDirectory</tt> during this phase.
+     *
+     * @param mavenProject the maven project
+     * @param webapplicationDirectory the target directory
+     * @throws MojoExecutionException if an error occurred while packaging the webapp
+     * @throws MojoFailureException if an unexpected error occurred while packaging the webapp
+     * @throws IOException if an error occurred while copying the files
+     */
+    public void buildWebapp( MavenProject mavenProject, File webapplicationDirectory )
+        throws MojoExecutionException, MojoFailureException, IOException
+    {
+
+        WebappStructure structure = new WebappStructure( mavenProject.getDependencies() );
+
+        // CHECKSTYLE_OFF: LineLength
+        final long startTime = System.currentTimeMillis();
+        getLog().info( "Assembling webapp [" + mavenProject.getArtifactId() + "] in [" + webapplicationDirectory + "]" );
+
+        final OverlayManager overlayManager =
+            new OverlayManager( overlays, mavenProject, getDependentWarIncludes(), getDependentWarExcludes(),
+                                currentProjectOverlay );
+        // CHECKSTYLE_ON: LineLength
+        List<FileUtils.FilterWrapper> defaultFilterWrappers;
+        try
+        {
+            MavenResourcesExecution mavenResourcesExecution = new MavenResourcesExecution();
+            mavenResourcesExecution.setEscapeString( escapeString );
+            mavenResourcesExecution.setSupportMultiLineFiltering( supportMultiLineFiltering );
+            mavenResourcesExecution.setMavenProject( mavenProject );
+
+            // if these are NOT set, just use the defaults, which are '${*}' and '@'.
+            mavenResourcesExecution.setDelimiters( delimiters, useDefaultDelimiters );
+
+            if ( nonFilteredFileExtensions != null )
+            {
+                mavenResourcesExecution.setNonFilteredFileExtensions( nonFilteredFileExtensions );
+            }
+            
+            if ( filters == null )
+            {
+                filters = getProject().getBuild().getFilters();
+            }
+            mavenResourcesExecution.setFilters( filters );
+            mavenResourcesExecution.setEscapedBackslashesInFilePath( escapedBackslashesInFilePath );
+            mavenResourcesExecution.setMavenSession( this.session );
+            mavenResourcesExecution.setEscapeString( this.escapeString );
+            mavenResourcesExecution.setSupportMultiLineFiltering( supportMultiLineFiltering );
+
+            defaultFilterWrappers = mavenFileFilter.getDefaultFilterWrappers( mavenResourcesExecution );
+
+        }
+        catch ( MavenFilteringException e )
+        {
+            getLog().error( "fail to build filtering wrappers " + e.getMessage() );
+            throw new MojoExecutionException( e.getMessage(), e );
+        }
+
+        final WarPackagingContext context =
+            new DefaultWarPackagingContext( webapplicationDirectory, structure, overlayManager, defaultFilterWrappers,
+                                            getNonFilteredFileExtensions(), filteringDeploymentDescriptors,
+                                            this.artifactFactory, resourceEncoding, useJvmChmod, failOnMissingWebXml,
+                                            outputTimestamp );
+
+        final List<WarPackagingTask> packagingTasks = getPackagingTasks( overlayManager );
+
+        for ( WarPackagingTask warPackagingTask : packagingTasks )
+        {
+            warPackagingTask.performPackaging( context );
+        }
+
+        getLog().debug( "Webapp assembled in [" + ( System.currentTimeMillis() - startTime ) + " msecs]" );
+
+    }
+
+    /**
+     * Returns a <tt>List</tt> of the {@link org.apache.maven.plugins.war.packaging.WarPackagingTask}
+     * instances to invoke to perform the packaging.
+     *
+     * @param overlayManager the overlay manager
+     * @return the list of packaging tasks
+     * @throws MojoExecutionException if the packaging tasks could not be built
+     */
+    private List<WarPackagingTask> getPackagingTasks( OverlayManager overlayManager )
+        throws MojoExecutionException
+    {
+        final List<WarPackagingTask> packagingTasks = new ArrayList<>();
+
+        packagingTasks.add( new CopyUserManifestTask() );
+
+        final List<Overlay> resolvedOverlays = overlayManager.getOverlays();
+        for ( Overlay overlay : resolvedOverlays )
+        {
+            if ( overlay.isCurrentProject() )
+            {
+                packagingTasks.add( new WarProjectPackagingTask( webResources, webXml, containerConfigXML,
+                                                                 currentProjectOverlay ) );
+            }
+            else
+            {
+                packagingTasks.add( new OverlayPackagingTask( overlay, currentProjectOverlay ) );
+            }
+        }
+        return packagingTasks;
+    }
+
+    /**
+     * WarPackagingContext default implementation
+     */
+    private class DefaultWarPackagingContext
+        implements WarPackagingContext
+    {
+        private final ArtifactFactory artifactFactory;
+
+        private final String resourceEncoding;
+
+        private final WebappStructure webappStructure;
+
+        private final File webappDirectory;
+
+        private final OverlayManager overlayManager;
+
+        private final List<FileUtils.FilterWrapper> filterWrappers;
+
+        private List<String> nonFilteredFileExtensions;
+
+        private boolean filteringDeploymentDescriptors;
+
+        private boolean useJvmChmod;
+
+        private final Boolean failOnMissingWebXml;
+
+        private final Collection<String> outdatedResources;
+
+        private final String outputTimestamp;
+
+        /**
+         * @param webappDirectory The web application directory.
+         * @param webappStructure The web app structure.
+         * @param overlayManager The overlay manager.
+         * @param filterWrappers The filter wrappers
+         * @param nonFilteredFileExtensions The non filtered file extensions.
+         * @param filteringDeploymentDescriptors The filtering deployment descriptors.
+         * @param artifactFactory The artifact factory.
+         * @param resourceEncoding The resource encoding.
+         * @param useJvmChmod use Jvm chmod or not.
+         * @param failOnMissingWebXml Flag to check whether we should ignore missing web.xml or not
+         * @param outputTimestamp the output timestamp for reproducible archive creation
+         */
+        DefaultWarPackagingContext( final File webappDirectory, final WebappStructure webappStructure,
+                                           final OverlayManager overlayManager,
+                                           List<FileUtils.FilterWrapper> filterWrappers,
+                                           List<String> nonFilteredFileExtensions,
+                                           boolean filteringDeploymentDescriptors, ArtifactFactory artifactFactory,
+                                           String resourceEncoding, boolean useJvmChmod,
+                                           final Boolean failOnMissingWebXml, String outputTimestamp )
+        {
+            this.webappDirectory = webappDirectory;
+            this.webappStructure = webappStructure;
+            this.overlayManager = overlayManager;
+            this.filterWrappers = filterWrappers;
+            this.artifactFactory = artifactFactory;
+            this.filteringDeploymentDescriptors = filteringDeploymentDescriptors;
+            this.nonFilteredFileExtensions =
+                nonFilteredFileExtensions == null ? Collections.<String>emptyList() : nonFilteredFileExtensions;
+            this.resourceEncoding = resourceEncoding;
+            // This is kinda stupid but if we loop over the current overlays and we request the path structure
+            // it will register it. This will avoid wrong warning messages in a later phase
+            for ( String overlayId : overlayManager.getOverlayIds() )
+            {
+                webappStructure.getStructure( overlayId );
+            }
+            this.useJvmChmod = useJvmChmod;
+            this.failOnMissingWebXml = failOnMissingWebXml;
+
+            if ( !webappDirectory.exists() )
+            {
+                outdatedResources = Collections.emptyList();
+            }
+            else if ( getWarSourceDirectory().toPath().equals( webappDirectory.toPath() ) )
+            {
+                getLog().info( "Can't detect outdated resources when running inplace goal" );
+                outdatedResources = Collections.emptyList();
+            }
+            else
+            {
+                outdatedResources = new ArrayList<>();
+                try
+                {
+                    Files.walkFileTree( webappDirectory.toPath(), new SimpleFileVisitor<Path>()
+                    {
+                        @Override
+                        public FileVisitResult visitFile( Path file, BasicFileAttributes attrs )
+                            throws IOException
+                        {
+                            outdatedResources.add( webappDirectory.toPath().relativize( file ).toString() );
+                            return super.visitFile( file, attrs );
+                        }
+                    } );
+                }
+                catch ( IOException e )
+                {
+                    getLog().warn( "Can't detect outdated resources", e );
+                }
+            }
+            this.outputTimestamp = outputTimestamp;
+        }
+
+        @Override
+        public MavenProject getProject()
+        {
+            return project;
+        }
+
+        @Override
+        public File getWebappDirectory()
+        {
+            return webappDirectory;
+        }
+
+        @Override
+        public File getClassesDirectory()
+        {
+            return classesDirectory;
+        }
+
+        @Override
+        public Log getLog()
+        {
+            return AbstractWarMojo.this.getLog();
+        }
+
+        @Override
+        public String getOutputFileNameMapping()
+        {
+            return outputFileNameMapping;
+        }
+
+        @Override
+        public File getWebappSourceDirectory()
+        {
+            return warSourceDirectory;
+        }
+
+        @Override
+        public String[] getWebappSourceIncludes()
+        {
+            return getIncludes();
+        }
+
+        @Override
+        public String[] getWebappSourceExcludes()
+        {
+            return getExcludes();
+        }
+
+        @Override
+        public boolean isWebappSourceIncludeEmptyDirectories()
+        {
+            return includeEmptyDirectories;
+        }
+
+        @Override
+        public boolean archiveClasses()
+        {
+            return archiveClasses;
+        }
+
+        @Override
+        public File getOverlaysWorkDirectory()
+        {
+            return workDirectory;
+        }
+
+        @Override
+        public ArchiverManager getArchiverManager()
+        {
+            return archiverManager;
+        }
+
+        @Override
+        public MavenArchiveConfiguration getArchive()
+        {
+            return archive;
+        }
+
+        @Override
+        public JarArchiver getJarArchiver()
+        {
+            return jarArchiver;
+        }
+
+        @Override
+        public List<String> getFilters()
+        {
+            return filters;
+        }
+
+        @Override
+        public WebappStructure getWebappStructure()
+        {
+            return webappStructure;
+        }
+
+        @Override
+        public List<String> getOwnerIds()
+        {
+            return overlayManager.getOverlayIds();
+        }
+
+        @Override
+        public MavenFileFilter getMavenFileFilter()
+        {
+            return mavenFileFilter;
+        }
+
+        @Override
+        public List<FileUtils.FilterWrapper> getFilterWrappers()
+        {
+            return filterWrappers;
+        }
+
+        @Override
+        public boolean isNonFilteredExtension( String fileName )
+        {
+            return !mavenResourcesFiltering.filteredFileExtension( fileName, nonFilteredFileExtensions );
+        }
+
+        @Override
+        public boolean isFilteringDeploymentDescriptors()
+        {
+            return filteringDeploymentDescriptors;
+        }
+
+        @Override
+        public ArtifactFactory getArtifactFactory()
+        {
+            return this.artifactFactory;
+        }
+
+        @Override
+        public MavenSession getSession()
+        {
+            return session;
+        }
+
+        @Override
+        public String getResourceEncoding()
+        {
+            return resourceEncoding;
+        }
+
+        @Override
+        public boolean isUseJvmChmod()
+        {
+            return useJvmChmod;
+        }
+
+        @Override
+        public Boolean isFailOnMissingWebXml()
+        {
+            return failOnMissingWebXml;
+        }
+
+        @Override
+        public void addResource( String resource )
+        {
+            outdatedResources.remove( resource.replace( '/', File.separatorChar ) );            
+        }
+
+        @Override
+        public void deleteOutdatedResources()
+        {
+            for ( String resource : outdatedResources )
+            {
+                getLog().info( "deleting outdated resource " + resource );
+                new File( getWebappDirectory(), resource ).delete();
+            }
+        }
+
+        @Override
+        public String getOutputTimestamp()
+        {
+            return outputTimestamp;
+        }
+    }
+
+    /**
+     * @return The Maven Project.
+     */
+    public MavenProject getProject()
+    {
+        return project;
+    }
+
+    /**
+     * @param project The project to be set.
+     */
+    public void setProject( MavenProject project )
+    {
+        this.project = project;
+    }
+
+    /**
+     * @return the classes directory.
+     */
+    public File getClassesDirectory()
+    {
+        return classesDirectory;
+    }
+
+    /**
+     * @param classesDirectory The classes directory to be set.
+     */
+    public void setClassesDirectory( File classesDirectory )
+    {
+        this.classesDirectory = classesDirectory;
+    }
+
+    /**
+     * @return {@link #webappDirectory}
+     */
+    public File getWebappDirectory()
+    {
+        return webappDirectory;
+    }
+
+    /**
+     * @param webappDirectory The web application directory.
+     */
+    public void setWebappDirectory( File webappDirectory )
+    {
+        this.webappDirectory = webappDirectory;
+    }
+
+    /**
+     * @return {@link #warSourceDirectory}
+     */
+    public File getWarSourceDirectory()
+    {
+        return warSourceDirectory;
+    }
+
+    /**
+     * @param warSourceDirectory {@link #warSourceDirectory}
+     */
+    public void setWarSourceDirectory( File warSourceDirectory )
+    {
+        this.warSourceDirectory = warSourceDirectory;
+    }
+
+    /**
+     * @return The {@link #webXml}
+     */
+    public File getWebXml()
+    {
+        return webXml;
+    }
+
+    /**
+     * @param webXml The {@link #webXml}
+     */
+    public void setWebXml( File webXml )
+    {
+        this.webXml = webXml;
+    }
+
+    /**
+     * @return {@link #containerConfigXML}
+     */
+    public File getContainerConfigXML()
+    {
+        return containerConfigXML;
+    }
+
+    /**
+     * @param containerConfigXML {@link #containerConfigXML}
+     */
+    public void setContainerConfigXML( File containerConfigXML )
+    {
+        this.containerConfigXML = containerConfigXML;
+    }
+
+    /**
+     * @return {@link #outputFileNameMapping}
+     */
+    public String getOutputFileNameMapping()
+    {
+        return outputFileNameMapping;
+    }
+
+    /**
+     * @param outputFileNameMapping {@link #outputFileNameMapping}
+     */
+    public void setOutputFileNameMapping( String outputFileNameMapping )
+    {
+        this.outputFileNameMapping = outputFileNameMapping;
+    }
+
+    /**
+     * @return {@link #overlays}
+     */
+    public List<Overlay> getOverlays()
+    {
+        return overlays;
+    }
+
+    /**
+     * @param overlays {@link #overlays}
+     */
+    public void setOverlays( List<Overlay> overlays )
+    {
+        this.overlays = overlays;
+    }
+
+    /**
+     * @param overlay add {@link #overlays}.
+     */
+    public void addOverlay( Overlay overlay )
+    {
+        overlays.add( overlay );
+    }
+
+    /**
+     * @return {@link #archiveClasses}
+     */
+    public boolean isArchiveClasses()
+    {
+        return archiveClasses;
+    }
+
+    /**
+     * @param archiveClasses {@link #archiveClasses}
+     */
+    public void setArchiveClasses( boolean archiveClasses )
+    {
+        this.archiveClasses = archiveClasses;
+    }
+
+    /**
+     * @return {@link JarArchiver}
+     */
+    public JarArchiver getJarArchiver()
+    {
+        return jarArchiver;
+    }
+
+    /**
+     * @param jarArchiver {@link JarArchiver}
+     */
+    public void setJarArchiver( JarArchiver jarArchiver )
+    {
+        this.jarArchiver = jarArchiver;
+    }
+
+    /**
+     * @return {@link #webResources}.
+     */
+    public Resource[] getWebResources()
+    {
+        return webResources;
+    }
+
+    /**
+     * @param webResources {@link #webResources}.
+     */
+    public void setWebResources( Resource[] webResources )
+    {
+        this.webResources = webResources;
+    }
+
+    /**
+     * @return {@link #filters}
+     */
+    public List<String> getFilters()
+    {
+        return filters;
+    }
+
+    /**
+     * @param filters {@link #filters}
+     */
+    public void setFilters( List<String> filters )
+    {
+        this.filters = filters;
+    }
+
+    /**
+     * @return {@link #workDirectory}
+     */
+    public File getWorkDirectory()
+    {
+        return workDirectory;
+    }
+
+    /**
+     * @param workDirectory {@link #workDirectory}
+     */
+    public void setWorkDirectory( File workDirectory )
+    {
+        this.workDirectory = workDirectory;
+    }
+
+    /**
+     * @return {@link #warSourceIncludes}
+     */
+    public String getWarSourceIncludes()
+    {
+        return warSourceIncludes;
+    }
+
+    /**
+     * @param warSourceIncludes {@link #warSourceIncludes}
+     */
+    public void setWarSourceIncludes( String warSourceIncludes )
+    {
+        this.warSourceIncludes = warSourceIncludes;
+    }
+
+    /**
+     * @return {@link #warSourceExcludes}
+     */
+    public String getWarSourceExcludes()
+    {
+        return warSourceExcludes;
+    }
+
+    /**
+     * @param warSourceExcludes {@link #warSourceExcludes}
+     */
+    public void setWarSourceExcludes( String warSourceExcludes )
+    {
+        this.warSourceExcludes = warSourceExcludes;
+    }
+
+    /**
+     * @return {@link #archive}
+     */
+    public MavenArchiveConfiguration getArchive()
+    {
+        return archive;
+    }
+
+    /**
+     * @return {@link #nonFilteredFileExtensions}
+     */
+    public List<String> getNonFilteredFileExtensions()
+    {
+        return nonFilteredFileExtensions;
+    }
+
+    /**
+     * @param nonFilteredFileExtensions {@link #nonFilteredFileExtensions}
+     */
+    public void setNonFilteredFileExtensions( List<String> nonFilteredFileExtensions )
+    {
+        this.nonFilteredFileExtensions = nonFilteredFileExtensions;
+    }
+
+    /**
+     * @return {@link #artifactFactory}
+     */
+    public ArtifactFactory getArtifactFactory()
+    {
+        return this.artifactFactory;
+    }
+
+    /**
+     * @param artifactFactory {@link #artifactFactory}
+     */
+    public void setArtifactFactory( ArtifactFactory artifactFactory )
+    {
+        this.artifactFactory = artifactFactory;
+    }
+
+    /**
+     * @return {@link #session}
+     */
+    protected MavenSession getSession()
+    {
+        return this.session;
+    }
+
+    /**
+     * @return {@link #recompressZippedFiles}
+     */
+    protected boolean isRecompressZippedFiles()
+    {
+        return recompressZippedFiles;
+    }
+
+    /**
+     * @return {@link #includeEmptyDirectories}
+     */
+    protected boolean isIncludeEmptyDirectories()
+    {
+        return includeEmptyDirectories;
+    }
+}
diff --git a/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/Overlay.java b/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/Overlay.java
new file mode 100644
index 000000000..c42f1c793
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/Overlay.java
@@ -0,0 +1,384 @@
+package org.apache.maven.plugins.war;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.artifact.Artifact;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * <p>
+ * An overlay is a skeleton WAR added to another WAR project in order to inject a functionality, resources or any other
+ * shared component.</p>
+ * 
+ * <p>Note that a particular WAR dependency can be added multiple times as an overlay with different includes/excludes
+ * filter; this allows building a fine grained overwriting policy.</p>
+ * 
+ * <p>The current project can also be described as an overlay and can not be specified twice. An overlay with no groupId
+ * and no artifactId represents the current project.</p>
+ *
+ * @author Stephane Nicoll
+ */
+public class Overlay
+{
+
+    /**
+     * The list of default includes.
+     */
+    public static final String[] DEFAULT_INCLUDES = new String[] { "**/**" };
+
+    /**
+     * The list of default excludes.
+     */
+    public static final String[] DEFAULT_EXCLUDES = new String[] { "META-INF/MANIFEST.MF" };
+
+    private String id;
+
+    private String groupId;
+
+    private String artifactId;
+
+    private String classifier = null;
+
+    private String[] includes = DEFAULT_INCLUDES;
+
+    private String[] excludes = DEFAULT_EXCLUDES;
+
+    private boolean filtered = false;
+
+    private boolean skip = false;
+
+    private Artifact artifact;
+
+    private String targetPath;
+
+    /** default overlay type is war */
+    private String type = "war";
+
+    /**
+     * Create instance.
+     */
+    public Overlay()
+    {
+        super();
+    }
+
+    /**
+     * @param groupId {@link #groupId}
+     * @param artifactId {@link #artifactId}
+     */
+    public Overlay( String groupId, String artifactId )
+    {
+        this();
+        this.groupId = groupId;
+        this.artifactId = artifactId;
+    }
+
+    /**
+     * Specify whether this overlay represents the current project or not.
+     *
+     * @return true if the overlay represents the current project, false otherwise
+     */
+    public boolean isCurrentProject()
+    {
+        return ( groupId == null && artifactId == null );
+    }
+
+    /**
+     * @return {@link Overlay} instance.
+     */
+    public static Overlay createInstance()
+    {
+        Overlay overlay = new Overlay();
+        overlay.setId( "currentBuild" );
+        return overlay;
+    }
+
+    // Getters and Setters
+
+    /**
+     * @return The id.
+     */
+    public String getId()
+    {
+        if ( id == null )
+        {
+            final StringBuilder sb = new StringBuilder();
+            sb.append( getGroupId() ).append( ":" ).append( getArtifactId() );
+            if ( getClassifier() != null )
+            {
+                sb.append( ":" ).append( getClassifier() );
+            }
+            id = sb.toString();
+        }
+        return id;
+    }
+
+    /**
+     * @param id The id.
+     */
+    public void setId( String id )
+    {
+        this.id = id;
+    }
+
+    /**
+     * @return {@link #groupId}
+     */
+    public String getGroupId()
+    {
+        return groupId;
+    }
+
+    /**
+     * @param groupId {@link #groupId}
+     */
+    public void setGroupId( String groupId )
+    {
+        this.groupId = groupId;
+    }
+
+    /**
+     * @return {@link #artifactId}
+     */
+    public String getArtifactId()
+    {
+        return artifactId;
+    }
+
+    /**
+     * @param artifactId {@link #artifactId}
+     */
+    public void setArtifactId( String artifactId )
+    {
+        this.artifactId = artifactId;
+    }
+
+    /**
+     * @return {@link #classifier}
+     */
+    public String getClassifier()
+    {
+        return classifier;
+    }
+
+    /**
+     * @param classifier {@link #classifier}
+     */
+    public void setClassifier( String classifier )
+    {
+        this.classifier = classifier;
+    }
+
+    /**
+     * @return {@link #includes}
+     */
+    public String[] getIncludes()
+    {
+        return includes;
+    }
+
+    /**
+     * @param includes {@link #includes}
+     */
+    public void setIncludes( String includes )
+    {
+        this.includes = parse( includes );
+    }
+
+    /**
+     * @param includes {@link #includes}
+     */
+    public void setIncludes( String[] includes )
+    {
+        this.includes = includes;
+    }
+
+    /**
+     * @return {@link #excludes}
+     */
+    public String[] getExcludes()
+    {
+        return excludes;
+    }
+
+    /**
+     * @param excludes {@link #excludes}
+     */
+    public void setExcludes( String excludes )
+    {
+        this.excludes = parse( excludes );
+    }
+
+    /**
+     * @param excludes {@link #excludes}
+     */
+    public void setExcludes( String[] excludes )
+    {
+        this.excludes = excludes;
+    }
+
+    /**
+     * @return {@link #filtered}
+     */
+    public boolean isFiltered()
+    {
+        return filtered;
+    }
+
+    /**
+     * @param filtered {@link #filtered}
+     */
+    public void setFiltered( boolean filtered )
+    {
+        this.filtered = filtered;
+    }
+
+    /**
+     * @return {@link #skip}
+     */
+    public boolean shouldSkip()
+    {
+        return skip;
+    }
+
+    /**
+     * @param skip {@link #skip}
+     */
+    public void setSkip( boolean skip )
+    {
+        this.skip = skip;
+    }
+
+    /**
+     * @return {@link #artifact}
+     */
+    public Artifact getArtifact()
+    {
+        return artifact;
+    }
+
+    /**
+     * @param artifact {@link #artifact}
+     */
+    public void setArtifact( Artifact artifact )
+    {
+        this.artifact = artifact;
+    }
+
+    /**
+     * @return {@link #targetPath}
+     */
+    public String getTargetPath()
+    {
+        return targetPath;
+    }
+
+    /**
+     * @param targetPath {@link #targetPath}
+     */
+    public void setTargetPath( String targetPath )
+    {
+        this.targetPath = targetPath;
+    }
+
+    /**
+     * @return {@link #type}
+     */
+    public String getType()
+    {
+        return type;
+    }
+
+    /**
+     * @param type {@link #type}
+     */
+    public void setType( String type )
+    {
+        this.type = type;
+    }
+
+    @Override
+    public String toString()
+    {
+        return " id " + getId();
+    }
+
+    @Override
+    public boolean equals( Object o )
+    {
+        if ( this == o )
+        {
+            return true;
+        }
+        if ( o == null || getClass() != o.getClass() )
+        {
+            return false;
+        }
+
+        Overlay overlay = (Overlay) o;
+
+        if ( excludes != null ? !Arrays.equals( excludes, overlay.excludes ) : overlay.excludes != null )
+        {
+            return false;
+        }
+        if ( getId() != null ? !getId().equals( overlay.getId() ) : overlay.getId() != null )
+        {
+            return false;
+        }
+        if ( includes != null ? !Arrays.equals( includes, overlay.includes ) : overlay.includes != null )
+        {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode()
+    {
+        int result;
+        result = ( getId() != null ? getId().hashCode() : 0 );
+        result = 31 * result + ( includes != null ? includes.hashCode() : 0 );
+        result = 31 * result + ( excludes != null ? excludes.hashCode() : 0 );
+        return result;
+    }
+
+    private String[] parse( String s )
+    {
+        final List<String> result = new ArrayList<>();
+        if ( s == null )
+        {
+            return result.toArray( new String[result.size()] );
+        }
+        else
+        {
+            String[] tokens = s.split( "," );
+            for ( String token : tokens )
+            {
+                result.add( token.trim() );
+            }
+            return result.toArray( new String[result.size()] );
+        }
+    }
+
+}
diff --git a/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/WarExplodedMojo.java b/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/WarExplodedMojo.java
new file mode 100644
index 000000000..1327068ce
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/WarExplodedMojo.java
@@ -0,0 +1,46 @@
+package org.apache.maven.plugins.war;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.ResolutionScope;
+
+/**
+ * Create an exploded webapp in a specified directory.
+ *
+ */
+@Mojo( name = "exploded", defaultPhase = LifecyclePhase.PACKAGE, threadSafe = true,
+                requiresDependencyResolution = ResolutionScope.RUNTIME )
+public class WarExplodedMojo
+    extends AbstractWarMojo
+{
+    @Override
+    public void execute()
+        throws MojoExecutionException, MojoFailureException
+    {
+        getLog().info( "Exploding webapp" );
+
+        buildExplodedWebapp( getWebappDirectory() );
+    }
+
+}
diff --git a/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/WarInPlaceMojo.java b/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/WarInPlaceMojo.java
new file mode 100644
index 000000000..9cfe02c64
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/WarInPlaceMojo.java
@@ -0,0 +1,43 @@
+package org.apache.maven.plugins.war;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.ResolutionScope;
+
+/**
+ * Generate the webapp in the WAR source directory.
+ *
+ */
+@Mojo( name = "inplace", requiresDependencyResolution = ResolutionScope.RUNTIME, threadSafe = true )
+public class WarInPlaceMojo
+    extends AbstractWarMojo
+{
+    @Override
+    public void execute()
+        throws MojoExecutionException, MojoFailureException
+    {
+        getLog().info( "Generating webapp in source directory [" + getWarSourceDirectory() + "]" );
+
+        buildExplodedWebapp( getWarSourceDirectory() );
+    }
+}
\ No newline at end of file
diff --git a/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/WarMojo.java b/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/WarMojo.java
new file mode 100644
index 000000000..e30c57151
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/WarMojo.java
@@ -0,0 +1,574 @@
+package org.apache.maven.plugins.war;
+
+/*
+ * 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.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.maven.archiver.MavenArchiver;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.DependencyResolutionRequiredException;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.Component;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.plugins.annotations.ResolutionScope;
+import org.apache.maven.plugins.war.util.ClassesPackager;
+import org.apache.maven.project.MavenProjectHelper;
+import org.codehaus.plexus.archiver.Archiver;
+import org.codehaus.plexus.archiver.ArchiverException;
+import org.codehaus.plexus.archiver.jar.ManifestException;
+import org.codehaus.plexus.archiver.war.WarArchiver;
+import org.codehaus.plexus.util.FileUtils;
+import org.codehaus.plexus.util.StringUtils;
+
+/**
+ * Build a WAR file.
+ *
+ * @author <a href="evenisse@apache.org">Emmanuel Venisse</a>
+ */
+@Mojo( name = "war", defaultPhase = LifecyclePhase.PACKAGE, threadSafe = true,
+                requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME )
+public class WarMojo
+    extends AbstractWarMojo
+{
+    /**
+     * The directory for the generated WAR.
+     */
+    @Parameter( defaultValue = "${project.build.directory}", required = true )
+    private String outputDirectory;
+
+    /**
+     * The name of the generated WAR.
+     */
+    @Parameter( defaultValue = "${project.build.finalName}", required = true, readonly = true )
+    private String warName;
+
+    /**
+     * Classifier to add to the generated WAR. If given, the artifact will be an attachment instead. The classifier will
+     * not be applied to the JAR file of the project - only to the WAR file.
+     */
+    @Parameter
+    private String classifier;
+
+    /**
+     * The comma separated list of tokens to exclude from the WAR before packaging. This option may be used to implement
+     * the skinny WAR use case. Note that you can use the Java Regular Expressions engine to include and exclude
+     * specific pattern using the expression %regex[]. Hint: read the about (?!Pattern).
+     *
+     * @since 2.1-alpha-2
+     */
+    @Parameter
+    private String packagingExcludes;
+
+    /**
+     * The comma separated list of tokens to include in the WAR before packaging. By default everything is included.
+     * This option may be used to implement the skinny WAR use case. Note that you can use the Java Regular Expressions
+     * engine to include and exclude specific pattern using the expression %regex[].
+     *
+     * @since 2.1-beta-1
+     */
+    @Parameter
+    private String packagingIncludes;
+
+    /**
+     * The WAR archiver.
+     */
+    @Component( role = Archiver.class, hint = "war" )
+    private WarArchiver warArchiver;
+
+    /**
+     */
+    @Component
+    private MavenProjectHelper projectHelper;
+
+    /**
+     * Whether this is the main artifact being built. Set to <code>false</code> if you don't want to install or deploy
+     * it to the local repository instead of the default one in an execution.
+     */
+    @Parameter( defaultValue = "true" )
+    private boolean primaryArtifact;
+
+    /**
+     * Whether classes (that is the content of the WEB-INF/classes directory) should be attached to the project as an
+     * additional artifact.
+     * <p>
+     * By default the classifier for the additional artifact is 'classes'. You can change it with the
+     * <code><![CDATA[<classesClassifier>someclassifier</classesClassifier>]]></code> parameter.
+     * </p>
+     * <p>
+     * If this parameter true, another project can depend on the classes by writing something like:
+     *
+     * <pre>
+     * <![CDATA[<dependency>
+     *   <groupId>myGroup</groupId>
+     *   <artifactId>myArtifact</artifactId>
+     *   <version>myVersion</myVersion>
+     *   <classifier>classes</classifier>
+     * </dependency>]]>
+     * </pre>
+     * </p>
+     *
+     * @since 2.1-alpha-2
+     */
+    @Parameter( defaultValue = "false" )
+    private boolean attachClasses;
+
+    /**
+     * The classifier to use for the attached classes artifact.
+     *
+     * @since 2.1-alpha-2
+     */
+    @Parameter( defaultValue = "classes" )
+    private String classesClassifier;
+
+    /**
+     * You can skip the execution of the plugin if you need to. Its use is NOT RECOMMENDED, but quite convenient on
+     * occasion.
+     *
+     * @since 3.0.0
+     */
+    @Parameter( property = "maven.war.skip", defaultValue = "false" )
+    private boolean skip;
+
+    // ----------------------------------------------------------------------
+    // Implementation
+    // ----------------------------------------------------------------------
+
+    /**
+     * Executes the WarMojo on the current project.
+     *
+     * @throws MojoExecutionException if an error occurred while building the webapp
+     * @throws MojoFailureException if an error.
+     */
+    @Override
+    public void execute()
+        throws MojoExecutionException, MojoFailureException
+    {
+
+        if ( isSkip() )
+        {
+            getLog().info( "Skipping the execution." );
+            return;
+        }
+
+        File warFile = getTargetWarFile();
+
+        try
+        {
+            performPackaging( warFile );
+        }
+        catch ( DependencyResolutionRequiredException | ArchiverException e )
+        {
+            throw new MojoExecutionException( "Error assembling WAR: " + e.getMessage(), e );
+        }
+        catch ( ManifestException | IOException e )
+        {
+            throw new MojoExecutionException( "Error assembling WAR", e );
+        }
+    }
+
+    /**
+     * Generates the webapp according to the <tt>mode</tt> attribute.
+     *
+     * @param warFile the target WAR file
+     * @throws IOException if an error occurred while copying files
+     * @throws ArchiverException if the archive could not be created
+     * @throws ManifestException if the manifest could not be created
+     * @throws DependencyResolutionRequiredException if an error occurred while resolving the dependencies
+     * @throws MojoExecutionException if the execution failed
+     * @throws MojoFailureException if a fatal exception occurred
+     */
+    private void performPackaging( File warFile )
+        throws IOException, ManifestException, DependencyResolutionRequiredException, MojoExecutionException,
+        MojoFailureException
+    {
+        getLog().info( "Packaging webapp" );
+
+        buildExplodedWebapp( getWebappDirectory() );
+
+        MavenArchiver archiver = new MavenArchiver();
+
+        archiver.setArchiver( warArchiver );
+
+        archiver.setCreatedBy( "Maven WAR Plugin", "org.apache.maven.plugins", "maven-war-plugin" );
+
+        archiver.setOutputFile( warFile );
+
+        // configure for Reproducible Builds based on outputTimestamp value
+        archiver.configureReproducible( outputTimestamp );
+
+        getLog().debug( "Excluding " + Arrays.asList( getPackagingExcludes() )
+            + " from the generated webapp archive." );
+        getLog().debug( "Including " + Arrays.asList( getPackagingIncludes() ) + " in the generated webapp archive." );
+
+        warArchiver.addDirectory( getWebappDirectory(), getPackagingIncludes(), getPackagingExcludes() );
+
+        final File webXmlFile = new File( getWebappDirectory(), "WEB-INF/web.xml" );
+        if ( webXmlFile.exists() )
+        {
+            warArchiver.setWebxml( webXmlFile );
+        }
+
+        warArchiver.setRecompressAddedZips( isRecompressZippedFiles() );
+
+        warArchiver.setIncludeEmptyDirs( isIncludeEmptyDirectories() );
+
+        if ( Boolean.FALSE.equals( failOnMissingWebXml )
+            || ( failOnMissingWebXml == null && isProjectUsingAtLeastServlet30() ) )
+        {
+            getLog().debug( "Build won't fail if web.xml file is missing." );
+            warArchiver.setExpectWebXml( false );
+        }
+
+        // create archive
+        archiver.createArchive( getSession(), getProject(), getArchive() );
+
+        // create the classes to be attached if necessary
+        if ( isAttachClasses() )
+        {
+            if ( isArchiveClasses() && getJarArchiver().getDestFile() != null )
+            {
+                // special handling in case of archived classes: MWAR-240
+                File targetClassesFile = getTargetClassesFile();
+                FileUtils.copyFile( getJarArchiver().getDestFile(), targetClassesFile );
+                projectHelper.attachArtifact( getProject(), "jar", getClassesClassifier(), targetClassesFile );
+            }
+            else
+            {
+                ClassesPackager packager = new ClassesPackager();
+                final File classesDirectory = packager.getClassesDirectory( getWebappDirectory() );
+                if ( classesDirectory.exists() )
+                {
+                    getLog().info( "Packaging classes" );
+                    packager.packageClasses( classesDirectory, getTargetClassesFile(), getJarArchiver(), getSession(),
+                                             getProject(), getArchive(), outputTimestamp );
+                    projectHelper.attachArtifact( getProject(), "jar", getClassesClassifier(), getTargetClassesFile() );
+                }
+            }
+        }
+
+        if ( this.classifier != null )
+        {
+            projectHelper.attachArtifact( getProject(), "war", this.classifier, warFile );
+        }
+        else
+        {
+            Artifact artifact = getProject().getArtifact();
+            if ( primaryArtifact )
+            {
+                artifact.setFile( warFile );
+            }
+            else if ( artifact.getFile() == null || artifact.getFile().isDirectory() )
+            {
+                artifact.setFile( warFile );
+            }
+        }
+    }
+
+    /**
+     * Determines if the current Maven project being built uses the Servlet 3.0 API (JSR 315)
+     * or Jakarta Servlet API.
+     * If it does then the <code>web.xml</code> file can be omitted.
+     * <p>
+     * This is done by checking if the interface <code>javax.servlet.annotation.WebServlet</code>
+     * or <code>jakarta.servlet.annotation.WebServlet</code> is in the compile-time
+     * dependencies (which includes provided dependencies) of the Maven project.
+     *
+     * @return <code>true</code> if the project being built depends on Servlet 3.0 API or Jakarta Servlet API,
+     *         <code>false</code> otherwise.
+     * @throws DependencyResolutionRequiredException if the compile elements can't be resolved.
+     * @throws MalformedURLException if the path to a dependency file can't be transformed to a URL.
+     */
+    private boolean isProjectUsingAtLeastServlet30()
+        throws DependencyResolutionRequiredException, MalformedURLException
+    {
+        List<String> classpathElements = getProject().getCompileClasspathElements();
+        URL[] urls = new URL[classpathElements.size()];
+        for ( int i = 0; i < urls.length; i++ )
+        {
+            urls[i] = new File( classpathElements.get( i ) ).toURI().toURL();
+        }
+        ClassLoader loader = new URLClassLoader( urls, Thread.currentThread().getContextClassLoader() );
+
+        return hasWebServletAnnotationClassInClasspath( loader );
+    }
+
+    private static boolean hasWebServletAnnotationClassInClasspath( ClassLoader loader )
+    {
+        return hasClassInClasspath( loader, "javax.servlet.annotation.WebServlet" )
+                || hasClassInClasspath( loader, "jakarta.servlet.annotation.WebServlet" );
+    }
+
+    private static boolean hasClassInClasspath( ClassLoader loader, String clazz )
+    {
+        try
+        {
+            Class.forName( clazz, false, loader );
+            return true;
+        }
+        catch ( ClassNotFoundException e )
+        {
+            return false;
+        }
+    }
+
+    /**
+     * @param basedir The basedir
+     * @param finalName The finalName
+     * @param classifier The classifier.
+     * @param type The type.
+     * @return {@link File}
+     */
+    protected static File getTargetFile( File basedir, String finalName, String classifier, String type )
+    {
+        if ( classifier == null )
+        {
+            classifier = "";
+        }
+        else if ( classifier.trim().length() > 0 && !classifier.startsWith( "-" ) )
+        {
+            classifier = "-" + classifier;
+        }
+
+        return new File( basedir, finalName + classifier + "." + type );
+    }
+
+    /**
+     * @return The war {@link File}
+     */
+    protected File getTargetWarFile()
+    {
+        return getTargetFile( new File( getOutputDirectory() ), getWarName(), getClassifier(), "war" );
+
+    }
+
+    /**
+     * @return The target class {@link File}
+     */
+    protected File getTargetClassesFile()
+    {
+        return getTargetFile( new File( getOutputDirectory() ), getWarName(), getClassesClassifier(), "jar" );
+    }
+
+    // Getters and Setters
+
+    /**
+     * @return {@link #classifier}
+     */
+    public String getClassifier()
+    {
+        return classifier;
+    }
+
+    /**
+     * @param classifier {@link #classifier}
+     */
+    public void setClassifier( String classifier )
+    {
+        this.classifier = classifier;
+    }
+
+    /**
+     * @return The package excludes.
+     */
+    public String[] getPackagingExcludes()
+    {
+        if ( StringUtils.isEmpty( packagingExcludes ) )
+        {
+            return new String[0];
+        }
+        else
+        {
+            return StringUtils.split( packagingExcludes, "," );
+        }
+    }
+
+    /**
+     * @param packagingExcludes {@link #packagingExcludes}
+     */
+    public void setPackagingExcludes( String packagingExcludes )
+    {
+        this.packagingExcludes = packagingExcludes;
+    }
+
+    /**
+     * @return The packaging includes.
+     */
+    public String[] getPackagingIncludes()
+    {
+        if ( StringUtils.isEmpty( packagingIncludes ) )
+        {
+            return new String[] { "**" };
+        }
+        else
+        {
+            return StringUtils.split( packagingIncludes, "," );
+        }
+    }
+
+    /**
+     * @param packagingIncludes {@link #packagingIncludes}
+     */
+    public void setPackagingIncludes( String packagingIncludes )
+    {
+        this.packagingIncludes = packagingIncludes;
+    }
+
+    /**
+     * @return {@link #outputDirectory}
+     */
+    public String getOutputDirectory()
+    {
+        return outputDirectory;
+    }
+
+    /**
+     * @param outputDirectory {@link #outputDirectory}
+     */
+    public void setOutputDirectory( String outputDirectory )
+    {
+        this.outputDirectory = outputDirectory;
+    }
+
+    /**
+     * @return {@link #warName}
+     */
+    public String getWarName()
+    {
+        return warName;
+    }
+
+    /**
+     * @param warName {@link #warName}
+     */
+    public void setWarName( String warName )
+    {
+        this.warName = warName;
+    }
+
+    /**
+     * @return {@link #warArchiver}
+     */
+    public WarArchiver getWarArchiver()
+    {
+        return warArchiver;
+    }
+
+    /**
+     * @param warArchiver {@link #warArchiver}
+     */
+    public void setWarArchiver( WarArchiver warArchiver )
+    {
+        this.warArchiver = warArchiver;
+    }
+
+    /**
+     * @return {@link #projectHelper}
+     */
+    public MavenProjectHelper getProjectHelper()
+    {
+        return projectHelper;
+    }
+
+    /**
+     * @param projectHelper {@link #projectHelper}
+     */
+    public void setProjectHelper( MavenProjectHelper projectHelper )
+    {
+        this.projectHelper = projectHelper;
+    }
+
+    /**
+     * @return {@link #primaryArtifact}
+     */
+    public boolean isPrimaryArtifact()
+    {
+        return primaryArtifact;
+    }
+
+    /**
+     * @param primaryArtifact {@link #primaryArtifact}
+     */
+    public void setPrimaryArtifact( boolean primaryArtifact )
+    {
+        this.primaryArtifact = primaryArtifact;
+    }
+
+    /**
+     * @return {@link #attachClasses}
+     */
+    public boolean isAttachClasses()
+    {
+        return attachClasses;
+    }
+
+    /**
+     * @param attachClasses {@link #attachClasses}
+     */
+    public void setAttachClasses( boolean attachClasses )
+    {
+        this.attachClasses = attachClasses;
+    }
+
+    /**
+     * @return {@link #classesClassifier}
+     */
+    public String getClassesClassifier()
+    {
+        return classesClassifier;
+    }
+
+    /**
+     * @param classesClassifier {@link #classesClassifier}
+     */
+    public void setClassesClassifier( String classesClassifier )
+    {
+        this.classesClassifier = classesClassifier;
+    }
+
+    /**
+     * @return {@link #failOnMissingWebXml}
+     */
+    public boolean isFailOnMissingWebXml()
+    {
+        return failOnMissingWebXml;
+    }
+
+    /**
+     * @param failOnMissingWebXml {@link #failOnMissingWebXml}
+     */
+    public void setFailOnMissingWebXml( boolean failOnMissingWebXml )
+    {
+        this.failOnMissingWebXml = failOnMissingWebXml;
+    }
+
+    public boolean isSkip()
+    {
+        return skip;
+    }
+}
diff --git a/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/overlay/DefaultOverlay.java b/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/overlay/DefaultOverlay.java
new file mode 100644
index 000000000..831a53a19
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/overlay/DefaultOverlay.java
@@ -0,0 +1,62 @@
+package org.apache.maven.plugins.war.overlay;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.plugins.war.Overlay;
+
+/**
+ * A default overlay implementation based on an {@link Artifact}.
+ *
+ * @author Stephane Nicoll
+ */
+public class DefaultOverlay
+    extends Overlay
+{
+
+    /**
+     * Creates an overlay for the specified artifact.
+     *
+     * @param a the artifact
+     */
+    public DefaultOverlay( Artifact a )
+    {
+        super();
+        setGroupId( a.getGroupId() );
+        setArtifactId( a.getArtifactId() );
+        setClassifier( a.getClassifier() );
+        setArtifact( a );
+        setType( a.getType() );
+    }
+
+    /**
+     * Creates an overlay for the specified artifact.
+     *
+     * @param a the artifact
+     * @param includes the includes to use
+     * @param excludes the excludes to use
+     */
+    public DefaultOverlay( Artifact a, String[] includes, String[] excludes )
+    {
+        this( a );
+        setIncludes( includes );
+        setExcludes( excludes );
+    }
+}
diff --git a/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/overlay/InvalidOverlayConfigurationException.java b/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/overlay/InvalidOverlayConfigurationException.java
new file mode 100644
index 000000000..3470ef57c
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/overlay/InvalidOverlayConfigurationException.java
@@ -0,0 +1,54 @@
+package org.apache.maven.plugins.war.overlay;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.plugin.MojoExecutionException;
+
+/**
+ * Thrown if the overlay configuration is invalid.
+ *
+ * @author Stephane Nicoll
+ */
+public class InvalidOverlayConfigurationException
+    extends MojoExecutionException
+{
+
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -9048144470408031414L;
+
+    /**
+     * @param string Set the message of the exception.
+     */
+    public InvalidOverlayConfigurationException( String string )
+    {
+        super( string );
+    }
+
+    /**
+     * @param string Set the message of the exception.
+     * @param throwable {@link Throwable}
+     */
+    public InvalidOverlayConfigurationException( String string, Throwable throwable )
+    {
+        super( string, throwable );
+    }
+}
diff --git a/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/overlay/OverlayManager.java b/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/overlay/OverlayManager.java
new file mode 100644
index 000000000..cf83d5e29
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/overlay/OverlayManager.java
@@ -0,0 +1,253 @@
+package org.apache.maven.plugins.war.overlay;
+
+/*
+ * 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.
+ */
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Objects;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
+import org.apache.maven.plugins.war.Overlay;
+import org.apache.maven.project.MavenProject;
+
+/**
+ * Manages the overlays.
+ *
+ * @author Stephane Nicoll
+ */
+public class OverlayManager
+{
+    private final List<Overlay> overlays;
+
+    private final MavenProject project;
+
+    private final List<Artifact> artifactsOverlays;
+
+    /**
+     * Creates a manager with the specified overlays.
+     * 
+     * Note that the list is potentially updated by the manager so a new list is created based on the overlays.
+     *
+     * @param overlays the overlays
+     * @param project the maven project
+     * @param defaultIncludes the default includes to use
+     * @param defaultExcludes the default excludes to use
+     * @param currentProjectOverlay the overlay for the current project
+     * @throws InvalidOverlayConfigurationException if the config is invalid
+     */
+    public OverlayManager( List<Overlay> overlays, MavenProject project, String[] defaultIncludes,
+                           String[] defaultExcludes, Overlay currentProjectOverlay )
+        throws InvalidOverlayConfigurationException
+    {
+        this.overlays = new ArrayList<>();
+        if ( overlays != null )
+        {
+            this.overlays.addAll( overlays );
+        }
+        this.project = project;
+
+        this.artifactsOverlays = getOverlaysAsArtifacts();
+
+        // Initialize
+        initialize( defaultIncludes, defaultExcludes, currentProjectOverlay );
+
+    }
+
+    /**
+     * Returns the resolved overlays.
+     *
+     * @return the overlays
+     */
+    public List<Overlay> getOverlays()
+    {
+        return overlays;
+    }
+
+    /**
+     * Returns the id of the resolved overlays.
+     *
+     * @return the overlay ids
+     */
+    public List<String> getOverlayIds()
+    {
+        final List<String> result = new ArrayList<>();
+        for ( Overlay overlay : overlays )
+        {
+            result.add( overlay.getId() );
+        }
+        return result;
+
+    }
+
+    /**
+     * Initializes the manager and validates the overlays configuration.
+     *
+     * @param defaultIncludes the default includes to use
+     * @param defaultExcludes the default excludes to use
+     * @param currentProjectOverlay the overlay for the current project
+     * @throws InvalidOverlayConfigurationException if the configuration is invalid
+     */
+    void initialize( String[] defaultIncludes, String[] defaultExcludes, Overlay currentProjectOverlay )
+        throws InvalidOverlayConfigurationException
+    {
+
+        // Build the list of configured artifacts and makes sure that each overlay
+        // refer to a valid artifact
+        final List<Artifact> configuredWarArtifacts = new ArrayList<>();
+        final ListIterator<Overlay> it = overlays.listIterator();
+        while ( it.hasNext() )
+        {
+            Overlay overlay = it.next();
+            if ( overlay == null )
+            {
+                throw new InvalidOverlayConfigurationException( "overlay could not be null." );
+            }
+            // If it's the current project, return the project instance
+            if ( overlay.isCurrentProject() )
+            {
+                overlay = currentProjectOverlay;
+                it.set( overlay );
+            }
+            // default includes/excludes - only if the overlay uses the default settings
+            if ( Arrays.equals( Overlay.DEFAULT_INCLUDES, overlay.getIncludes() )
+                && Arrays.equals( Overlay.DEFAULT_EXCLUDES, overlay.getExcludes() ) )
+            {
+                overlay.setIncludes( defaultIncludes );
+                overlay.setExcludes( defaultExcludes );
+            }
+
+            final Artifact artifact = getAssociatedArtifact( overlay );
+            if ( artifact != null )
+            {
+                configuredWarArtifacts.add( artifact );
+                overlay.setArtifact( artifact );
+            }
+        }
+
+        // Build the list of missing overlays
+        for ( Artifact artifact : artifactsOverlays )
+        {
+            if ( !configuredWarArtifacts.contains( artifact ) )
+            {
+                // Add a default overlay for the given artifact which will be applied after
+                // the ones that have been configured
+                overlays.add( new DefaultOverlay( artifact, defaultIncludes, defaultExcludes ) );
+            }
+        }
+
+        // Final validation, make sure that the current project is in there. Otherwise add it first
+        for ( Overlay overlay : overlays )
+        {
+            if ( overlay.equals( currentProjectOverlay ) )
+            {
+                return;
+            }
+        }
+        overlays.add( 0, currentProjectOverlay );
+    }
+
+    /**
+     * Returns the Artifact associated to the specified overlay.
+     * 
+     * If the overlay defines the current project, <tt>null</tt> is returned. If no artifact could not be found for the
+     * overlay a InvalidOverlayConfigurationException is thrown.
+     *
+     * @param overlay an overlay
+     * @return the artifact associated to the overlay
+     * @throws org.apache.maven.plugins.war.overlay.InvalidOverlayConfigurationException if the overlay does not have an
+     *             associated artifact
+     */
+    Artifact getAssociatedArtifact( final Overlay overlay )
+        throws InvalidOverlayConfigurationException
+    {
+        if ( overlay.isCurrentProject() )
+        {
+            return null;
+        }
+
+        for ( Artifact artifact : artifactsOverlays )
+        {
+            // Handle classifier dependencies properly (clash management)
+            if ( compareOverlayWithArtifact( overlay, artifact ) )
+            {
+                return artifact;
+            }
+        }
+
+        // maybe its a project dependencies zip or an other type
+        Set<Artifact> projectArtifacts = this.project.getDependencyArtifacts();
+        if ( projectArtifacts != null )
+        {
+            for ( Artifact artifact : projectArtifacts )
+            {
+                if ( compareOverlayWithArtifact( overlay, artifact ) )
+                {
+                    return artifact;
+                }
+            }
+        }
+        // CHECKSTYLE_OFF: LineLength
+        throw new InvalidOverlayConfigurationException( "overlay [" + overlay + "] is not a dependency of the project." );
+        // CHECKSTYLE_ON: LineLength
+
+    }
+
+    /**
+     * Compare groupId && artifactId && type && classifier.
+     *
+     * @param overlay the overlay
+     * @param artifact the artifact
+     * @return boolean true if equals
+     */
+    private boolean compareOverlayWithArtifact( Overlay overlay, Artifact artifact )
+    {
+        return ( Objects.equals( overlay.getGroupId(), artifact.getGroupId() )
+            && Objects.equals( overlay.getArtifactId(), artifact.getArtifactId() )
+            && Objects.equals( overlay.getType(), artifact.getType() )
+        // MWAR-241 Make sure to treat null and "" as equal when comparing the classifier
+        && Objects.equals( Objects.toString( overlay.getClassifier() ),
+                           Objects.toString( artifact.getClassifier() ) ) );
+    }
+
+    /**
+     * Returns a list of WAR {@link org.apache.maven.artifact.Artifact} describing the overlays of the current project.
+     *
+     * @return the overlays as artifacts objects
+     */
+    private List<Artifact> getOverlaysAsArtifacts()
+    {
+        ScopeArtifactFilter filter = new ScopeArtifactFilter( Artifact.SCOPE_RUNTIME );
+        final Set<Artifact> artifacts = project.getArtifacts();
+
+        final List<Artifact> result = new ArrayList<>();
+        for ( Artifact artifact : artifacts )
+        {
+            if ( !artifact.isOptional() && filter.include( artifact ) && ( "war".equals( artifact.getType() ) ) )
+            {
+                result.add( artifact );
+            }
+        }
+        return result;
+    }
+}
diff --git a/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/packaging/AbstractWarPackagingTask.java b/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/packaging/AbstractWarPackagingTask.java
new file mode 100644
index 000000000..e230f6cf6
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/packaging/AbstractWarPackagingTask.java
@@ -0,0 +1,492 @@
+package org.apache.maven.plugins.war.packaging;
+
+/*
+ * 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.
+ */
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.commons.io.input.XmlStreamReader;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugins.war.util.PathSet;
+import org.apache.maven.plugins.war.util.WebappStructure;
+import org.apache.maven.shared.filtering.MavenFilteringException;
+import org.apache.maven.shared.mapping.MappingUtils;
+import org.codehaus.plexus.archiver.ArchiverException;
+import org.codehaus.plexus.archiver.UnArchiver;
+import org.codehaus.plexus.archiver.jar.JarArchiver;
+import org.codehaus.plexus.archiver.manager.NoSuchArchiverException;
+import org.codehaus.plexus.interpolation.InterpolationException;
+import org.codehaus.plexus.util.DirectoryScanner;
+import org.codehaus.plexus.util.FileUtils;
+
+/**
+ * @author Stephane Nicoll
+ */
+public abstract class AbstractWarPackagingTask
+    implements WarPackagingTask
+{
+    /**
+     * The default list of includes.
+     */
+    public static final String[] DEFAULT_INCLUDES = { "**/**" };
+
+    /**
+     * The {@code WEB-INF} path.
+     */
+    public static final String WEB_INF_PATH = "WEB-INF";
+
+    /**
+     * The {@code META-INF} path.
+     */
+    public static final String META_INF_PATH = "META-INF";
+
+    /**
+     * The {@code classes} path.
+     */
+    public static final String CLASSES_PATH = "WEB-INF/classes/";
+
+    /**
+     * The {@code lib} path.
+     */
+    public static final String LIB_PATH = "WEB-INF/lib/";
+
+    /**
+     * Copies the files if possible with an optional target prefix.
+     * 
+     * Copy uses a first-win strategy: files that have already been copied by previous tasks are ignored. This method
+     * makes sure to update the list of protected files which gives the list of files that have already been copied.
+     * 
+     * If the structure of the source directory is not the same as the root of the webapp, use the <tt>targetPrefix</tt>
+     * parameter to specify in which particular directory the files should be copied. Use <tt>null</tt> to copy the
+     * files with the same structure
+     *
+     * @param sourceId the source id
+     * @param context the context to use
+     * @param sourceBaseDir the base directory from which the <tt>sourceFilesSet</tt> will be copied
+     * @param sourceFilesSet the files to be copied
+     * @param targetPrefix the prefix to add to the target file name
+     * @param filtered filter or not.
+     * @throws IOException if an error occurred while copying the files
+     * @throws MojoExecutionException if an error occurs.
+     */
+    protected void copyFiles( String sourceId, WarPackagingContext context, File sourceBaseDir, PathSet sourceFilesSet,
+                              String targetPrefix, boolean filtered )
+        throws IOException, MojoExecutionException
+    {
+        for ( String fileToCopyName : sourceFilesSet.paths() )
+        {
+            final File sourceFile = new File( sourceBaseDir, fileToCopyName );
+
+            String destinationFileName;
+            if ( targetPrefix == null )
+            {
+                destinationFileName = fileToCopyName;
+            }
+            else
+            {
+                destinationFileName = targetPrefix + fileToCopyName;
+            }
+
+            if ( filtered && !context.isNonFilteredExtension( sourceFile.getName() ) )
+            {
+                copyFilteredFile( sourceId, context, sourceFile, destinationFileName );
+            }
+            else
+            {
+                copyFile( sourceId, context, sourceFile, destinationFileName );
+            }
+        }
+    }
+
+    /**
+     * Copies the files if possible as is.
+     * 
+     * Copy uses a first-win strategy: files that have already been copied by previous tasks are ignored. This method
+     * makes sure to update the list of protected files which gives the list of files that have already been copied.
+     *
+     * @param sourceId the source id
+     * @param context the context to use
+     * @param sourceBaseDir the base directory from which the <tt>sourceFilesSet</tt> will be copied
+     * @param sourceFilesSet the files to be copied
+     * @param filtered filter or not.
+     * @throws IOException if an error occurred while copying the files
+     * @throws MojoExecutionException break the build.
+     */
+    protected void copyFiles( String sourceId, WarPackagingContext context, File sourceBaseDir, PathSet sourceFilesSet,
+                              boolean filtered )
+        throws IOException, MojoExecutionException
+    {
+        copyFiles( sourceId, context, sourceBaseDir, sourceFilesSet, null, filtered );
+    }
+
+    /**
+     * Copy the specified file if the target location has not yet already been used.
+     * 
+     * The <tt>targetFileName</tt> is the relative path according to the root of the generated web application.
+     *
+     * @param sourceId the source id
+     * @param context the context to use
+     * @param file the file to copy
+     * @param targetFilename the relative path according to the root of the webapp
+     * @throws IOException if an error occurred while copying
+     */
+    // CHECKSTYLE_OFF: LineLength
+    protected void copyFile( String sourceId, final WarPackagingContext context, final File file, String targetFilename )
+        throws IOException
+    // CHECKSTYLE_ON: LineLength
+    {
+        final File targetFile = new File( context.getWebappDirectory(), targetFilename );
+
+        if ( file.isFile() )
+        {
+            context.getWebappStructure().registerFile( sourceId, targetFilename,
+           new WebappStructure.RegistrationCallback()
+           {
+               public void registered( String ownerId, String targetFilename )
+                   throws IOException
+               {
+                   copyFile( context, file, targetFile, targetFilename,
+                             false );
+               }
+    
+               public void alreadyRegistered( String ownerId,
+                                              String targetFilename )
+                   throws IOException
+               {
+                   copyFile( context, file, targetFile, targetFilename,
+                             true );
+               }
+    
+               public void refused( String ownerId, String targetFilename,
+                                    String actualOwnerId )
+                   throws IOException
+               {
+                   context.getLog().debug( " - "
+                                               + targetFilename
+                                               + " wasn't copied because it has "
+                                               + "already been packaged for overlay ["
+                                               + actualOwnerId + "]." );
+               }
+    
+               public void superseded( String ownerId,
+                                       String targetFilename,
+                                       String deprecatedOwnerId )
+                   throws IOException
+               {
+                   context.getLog().info( "File ["
+                                              + targetFilename
+                                              + "] belonged to overlay ["
+                                              + deprecatedOwnerId
+                                              + "] so it will be overwritten." );
+                   copyFile( context, file, targetFile, targetFilename,
+                             false );
+               }
+    
+               public void supersededUnknownOwner( String ownerId,
+                                                   String targetFilename,
+                                                   String unknownOwnerId )
+                   throws IOException
+               {
+                   // CHECKSTYLE_OFF: LineLength
+                   context.getLog().warn( "File ["
+                                              + targetFilename
+                                              + "] belonged to overlay ["
+                                              + unknownOwnerId
+                                              + "] which does not exist anymore in the current project. It is recommended to invoke "
+                                              + "clean if the dependencies of the project changed." );
+                   // CHECKSTYLE_ON: LineLength
+                   copyFile( context, file, targetFile, targetFilename,
+                             false );
+               }
+           } );
+        }
+        else if ( !targetFile.exists() && !targetFile.mkdirs() )
+        {
+            context.getLog().info( "Failed to create directory " + targetFile.getAbsolutePath() );
+        }
+    }
+
+    /**
+     * Copy the specified file if the target location has not yet already been used and filter its content with the
+     * configured filter properties.
+     * 
+     * The <tt>targetFileName</tt> is the relative path according to the root of the generated web application.
+     *
+     * @param sourceId the source id
+     * @param context the context to use
+     * @param file the file to copy
+     * @param targetFilename the relative path according to the root of the webapp
+     * @return true if the file has been copied, false otherwise
+     * @throws IOException if an error occurred while copying
+     * @throws MojoExecutionException if an error occurred while retrieving the filter properties
+     */
+    protected boolean copyFilteredFile( String sourceId, final WarPackagingContext context, File file,
+                                        String targetFilename )
+        throws IOException, MojoExecutionException
+    {
+        context.addResource( targetFilename );
+
+        if ( context.getWebappStructure().registerFile( sourceId, targetFilename ) )
+        {
+            final File targetFile = new File( context.getWebappDirectory(), targetFilename );
+            final String encoding;
+            try
+            {
+                if ( isXmlFile( file ) )
+                {
+                    // For xml-files we extract the encoding from the files
+                    encoding = getEncoding( file );
+                }
+                else
+                {
+                    // For all others we use the configured encoding
+                    encoding = context.getResourceEncoding();
+                }
+                // fix for MWAR-36, ensures that the parent dir are created first
+                targetFile.getParentFile().mkdirs();
+
+                context.getMavenFileFilter().copyFile( file, targetFile, true, context.getFilterWrappers(), encoding );
+            }
+            catch ( MavenFilteringException e )
+            {
+                throw new MojoExecutionException( e.getMessage(), e );
+            }
+            // CHECKSTYLE_OFF: LineLength
+            // Add the file to the protected list
+            context.getLog().debug( " + " + targetFilename + " has been copied (filtered encoding='" + encoding + "')." );
+            // CHECKSTYLE_ON: LineLength
+            return true;
+        }
+        else
+        {
+            context.getLog().debug( " - " + targetFilename
+                                        + " wasn't copied because it has already been packaged (filtered)." );
+            return false;
+        }
+    }
+
+    /**
+     * Unpacks the specified file to the specified directory.
+     *
+     * @param context the packaging context
+     * @param file the file to unpack
+     * @param unpackDirectory the directory to use for th unpacked file
+     * @throws MojoExecutionException if an error occurred while unpacking the file
+     */
+    protected void doUnpack( WarPackagingContext context, File file, File unpackDirectory )
+        throws MojoExecutionException
+    {
+        String archiveExt = FileUtils.getExtension( file.getAbsolutePath() ).toLowerCase();
+
+        try
+        {
+            UnArchiver unArchiver = context.getArchiverManager().getUnArchiver( archiveExt );
+            unArchiver.setSourceFile( file );
+            unArchiver.setDestDirectory( unpackDirectory );
+            unArchiver.setOverwrite( true );
+            unArchiver.extract();
+        }
+        catch ( ArchiverException e )
+        {
+            throw new MojoExecutionException( "Error unpacking file [" + file.getAbsolutePath() + "]" + " to ["
+                + unpackDirectory.getAbsolutePath() + "]", e );
+        }
+        catch ( NoSuchArchiverException e )
+        {
+            context.getLog().warn( "Skip unpacking dependency file [" + file.getAbsolutePath()
+                                       + " with unknown extension [" + archiveExt + "]" );
+        }
+    }
+
+    /**
+     * Copy file from source to destination. The directories up to <code>destination</code> will be created if they
+     * don't already exist. if the <code>onlyIfModified</code> flag is <tt>false</tt>, <code>destination</code> will be
+     * overwritten if it already exists. If the flag is <tt>true</tt> destination will be overwritten if it's not up to
+     * date.
+     *
+     * @param context the packaging context
+     * @param source an existing non-directory <code>File</code> to copy bytes from
+     * @param destination a non-directory <code>File</code> to write bytes to (possibly overwriting).
+     * @param targetFilename the relative path of the file from the webapp root directory
+     * @param onlyIfModified if true, copy the file only if the source has changed, always copy otherwise
+     * @return true if the file has been copied/updated, false otherwise
+     * @throws IOException if <code>source</code> does not exist, <code>destination</code> cannot be written to, or an
+     *             IO error occurs during copying
+     */
+    protected boolean copyFile( WarPackagingContext context, File source, File destination, String targetFilename,
+                                boolean onlyIfModified )
+        throws IOException
+    {
+        context.addResource( targetFilename );
+
+        if ( onlyIfModified && destination.lastModified() >= source.lastModified() )
+        {
+            context.getLog().debug( " * " + targetFilename + " is up to date." );
+            return false;
+        }
+        else
+        {
+            if ( source.isDirectory() )
+            {
+                context.getLog().warn( " + " + targetFilename + " is packaged from the source folder" );
+
+                try
+                {
+                    JarArchiver archiver = context.getJarArchiver();
+                    archiver.addDirectory( source );
+                    archiver.setDestFile( destination );
+                    archiver.createArchive();
+                }
+                catch ( ArchiverException e )
+                {
+                    String msg = "Failed to create " + targetFilename;
+                    context.getLog().error( msg, e );
+                    IOException ioe = new IOException( msg );
+                    ioe.initCause( e );
+                    throw ioe;
+                }
+            }
+            else
+            {
+                FileUtils.copyFile( source.getCanonicalFile(), destination );
+                // preserve timestamp
+                destination.setLastModified( source.lastModified() );
+                context.getLog().debug( " + " + targetFilename + " has been copied." );
+            }
+            return true;
+        }
+    }
+
+    /**
+     * Get the encoding from an XML-file.
+     *
+     * @param webXml the XML-file
+     * @return The encoding of the XML-file, or UTF-8 if it's not specified in the file
+     * @throws java.io.IOException if an error occurred while reading the file
+     */
+    protected String getEncoding( File webXml )
+        throws IOException
+    {
+        try ( XmlStreamReader xmlReader = new XmlStreamReader( webXml ) )
+        {
+            return xmlReader.getEncoding();
+        }
+    }
+
+    /**
+     * Returns the file to copy. If the includes are <tt>null</tt> or empty, the default includes are used.
+     *
+     * @param baseDir the base directory to start from
+     * @param includes the includes
+     * @param excludes the excludes
+     * @return the files to copy
+     */
+    protected PathSet getFilesToIncludes( File baseDir, String[] includes, String[] excludes )
+    {
+        return getFilesToIncludes( baseDir, includes, excludes, false );
+    }
+
+    /**
+     * Returns the file to copy. If the includes are <tt>null</tt> or empty, the default includes are used.
+     *
+     * @param baseDir the base directory to start from
+     * @param includes the includes
+     * @param excludes the excludes
+     * @param includeDirectories include directories yes or not.
+     * @return the files to copy
+     */
+    // CHECKSTYLE_OFF: LineLength
+    protected PathSet getFilesToIncludes( File baseDir, String[] includes, String[] excludes, boolean includeDirectories )
+    // CHECKSTYLE_ON: LineLength
+    {
+        final DirectoryScanner scanner = new DirectoryScanner();
+        scanner.setBasedir( baseDir );
+
+        if ( excludes != null )
+        {
+            scanner.setExcludes( excludes );
+        }
+        scanner.addDefaultExcludes();
+
+        if ( includes != null && includes.length > 0 )
+        {
+            scanner.setIncludes( includes );
+        }
+        else
+        {
+            scanner.setIncludes( DEFAULT_INCLUDES );
+        }
+
+        scanner.scan();
+
+        PathSet pathSet = new PathSet( scanner.getIncludedFiles() );
+
+        if ( includeDirectories )
+        {
+            pathSet.addAll( scanner.getIncludedDirectories() );
+        }
+
+        return pathSet;
+    }
+
+    /**
+     * Returns the final name of the specified artifact.
+     * 
+     * If the <tt>outputFileNameMapping</tt> is set, it is used, otherwise the standard naming scheme is used.
+     *
+     * @param context the packaging context
+     * @param artifact the artifact
+     * @return the converted filename of the artifact
+     * @throws InterpolationException in case of interpolation problem.
+     */
+    protected String getArtifactFinalName( WarPackagingContext context, Artifact artifact )
+        throws InterpolationException
+    {
+        if ( context.getOutputFileNameMapping() != null )
+        {
+            return MappingUtils.evaluateFileNameMapping( context.getOutputFileNameMapping(), artifact );
+        }
+
+        String classifier = artifact.getClassifier();
+        if ( ( classifier != null ) && !( "".equals( classifier.trim() ) ) )
+        {
+            return MappingUtils.evaluateFileNameMapping( MappingUtils.DEFAULT_FILE_NAME_MAPPING_CLASSIFIER, artifact );
+        }
+        else
+        {
+            return MappingUtils.evaluateFileNameMapping( MappingUtils.DEFAULT_FILE_NAME_MAPPING, artifact );
+        }
+
+    }
+
+    /**
+     * Returns <code>true</code> if the <code>File</code>-object is a file (not a directory) that is not
+     * <code>null</code> and has a file name that ends in ".xml".
+     *
+     * @param file The file to check
+     * @return <code>true</code> if the file is an xml-file, otherwise <code>false</code>
+     * @since 2.3
+     */
+    private boolean isXmlFile( File file )
+    {
+        return file != null && file.isFile() && file.getName().endsWith( ".xml" );
+    }
+}
diff --git a/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/packaging/ArtifactsPackagingTask.java b/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/packaging/ArtifactsPackagingTask.java
new file mode 100644
index 000000000..2fa484d6d
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/packaging/ArtifactsPackagingTask.java
@@ -0,0 +1,187 @@
+package org.apache.maven.plugins.war.packaging;
+
+/*
+ * 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.
+ */
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugins.war.Overlay;
+import org.codehaus.plexus.interpolation.InterpolationException;
+
+/**
+ * Handles the artifacts that needs to be packaged in the web application.
+ *
+ * @author Stephane Nicoll
+ */
+public class ArtifactsPackagingTask
+    extends AbstractWarPackagingTask
+{
+
+    /**
+     * The {@code tld} path.
+     */
+    public static final String TLD_PATH = "WEB-INF/tld/";
+
+    /**
+     * The {@code services} path.
+     */
+    public static final String SERVICES_PATH = "WEB-INF/services/";
+
+    /**
+     * The {@code modules} path.
+     */
+    public static final String MODULES_PATH = "WEB-INF/modules/";
+
+    /**
+     * The {@code extensions} path.
+     */
+    public static final String EXTENSIONS_PATH = "WEB-INF/extensions/";
+
+    private final Set<Artifact> artifacts;
+
+    private final String id;
+
+    /**
+     * @param artifacts {@link #artifacts}
+     * @param currentProjectOverlay {@link #id}
+     */
+    public ArtifactsPackagingTask( Set<Artifact> artifacts, Overlay currentProjectOverlay )
+    {
+        this.artifacts = artifacts;
+        this.id = currentProjectOverlay.getId();
+    }
+
+    @Override
+    public void performPackaging( WarPackagingContext context )
+        throws MojoExecutionException
+    {
+        try
+        {
+            final ScopeArtifactFilter filter = new ScopeArtifactFilter( Artifact.SCOPE_RUNTIME );
+            final List<String> duplicates = findDuplicates( context, artifacts );
+
+            for ( Artifact artifact : artifacts )
+            {
+                String targetFileName = getArtifactFinalName( context, artifact );
+
+                context.getLog().debug( "Processing: " + targetFileName );
+
+                if ( duplicates.contains( targetFileName ) )
+                {
+                    context.getLog().debug( "Duplicate found: " + targetFileName );
+                    targetFileName = artifact.getGroupId() + "-" + targetFileName;
+                    context.getLog().debug( "Renamed to: " + targetFileName );
+                }
+                context.getWebappStructure().registerTargetFileName( artifact, targetFileName );
+
+                if ( !artifact.isOptional() && filter.include( artifact ) )
+                {
+                    try
+                    {
+                        String type = artifact.getType();
+                        if ( "tld".equals( type ) )
+                        {
+                            copyFile( id, context, artifact.getFile(), TLD_PATH + targetFileName );
+                        }
+                        else if ( "aar".equals( type ) )
+                        {
+                            copyFile( id, context, artifact.getFile(), SERVICES_PATH + targetFileName );
+                        }
+                        else if ( "mar".equals( type ) )
+                        {
+                            copyFile( id, context, artifact.getFile(), MODULES_PATH + targetFileName );
+                        }
+                        else if ( "xar".equals( type ) )
+                        {
+                            copyFile( id, context, artifact.getFile(), EXTENSIONS_PATH + targetFileName );
+                        }
+                        else if ( "jar".equals( type ) || "ejb".equals( type ) || "ejb-client".equals( type )
+                            || "test-jar".equals( type ) || "bundle".equals( type ) )
+                        {
+                            copyFile( id, context, artifact.getFile(), LIB_PATH + targetFileName );
+                        }
+                        else if ( "par".equals( type ) )
+                        {
+                            targetFileName = targetFileName.substring( 0, targetFileName.lastIndexOf( '.' ) ) + ".jar";
+                            copyFile( id, context, artifact.getFile(), LIB_PATH + targetFileName );
+                        }
+                        else if ( "war".equals( type ) )
+                        {
+                            // Nothing to do here, it is an overlay and it's already handled
+                            context.getLog().debug( "war artifacts are handled as overlays, ignoring [" + artifact
+                                                        + "]" );
+                        }
+                        else if ( "zip".equals( type ) )
+                        {
+                            // Nothing to do here, it is an overlay and it's already handled
+                            context.getLog().debug( "zip artifacts are handled as overlays, ignoring [" + artifact
+                                                        + "]" );
+                        }
+                        else
+                        {
+                            context.getLog().debug( "Artifact of type [" + type + "] is not supported, ignoring ["
+                                                        + artifact + "]" );
+                        }
+                    }
+                    catch ( IOException e )
+                    {
+                        throw new MojoExecutionException( "Failed to copy file for artifact [" + artifact + "]", e );
+                    }
+                }
+            }
+        }
+        catch ( InterpolationException e )
+        {
+            throw new MojoExecutionException( e.getMessage(), e );
+        }
+    }
+
+    /**
+     * Searches a set of artifacts for duplicate filenames and returns a list of duplicates.
+     *
+     * @param context the packaging context
+     * @param artifacts set of artifacts
+     * @return List of duplicated artifacts as bundling file names
+     */
+    private List<String> findDuplicates( WarPackagingContext context, Set<Artifact> artifacts )
+        throws InterpolationException
+    {
+        List<String> duplicates = new ArrayList<>();
+        List<String> identifiers = new ArrayList<>();
+        for ( Artifact artifact : artifacts )
+        {
+            String candidate = getArtifactFinalName( context, artifact );
+            if ( identifiers.contains( candidate ) )
+            {
+                duplicates.add( candidate );
+            }
+            else
+            {
+                identifiers.add( candidate );
+            }
+        }
+        return duplicates;
+    }
+}
diff --git a/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/packaging/ClassesPackagingTask.java b/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/packaging/ClassesPackagingTask.java
new file mode 100644
index 000000000..ea136a695
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/packaging/ClassesPackagingTask.java
@@ -0,0 +1,128 @@
+package org.apache.maven.plugins.war.packaging;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.factory.ArtifactFactory;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugins.war.Overlay;
+import org.apache.maven.plugins.war.util.ClassesPackager;
+import org.apache.maven.plugins.war.util.PathSet;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.interpolation.InterpolationException;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * Handles the classes directory that needs to be packaged in the web application.
+ * 
+ * Based on the {@link WarPackagingContext#archiveClasses()} flag, the resources are either copied into to
+ * <tt>WEB-INF/classes</tt> directory or archived in a jar within the <tt>WEB-INF/lib</tt> directory.
+ *
+ * @author Stephane Nicoll
+ */
+public class ClassesPackagingTask
+    extends AbstractWarPackagingTask
+{
+    private final Overlay currentProjectOverlay;
+
+    /**
+     * @param currentProjectOverlay {@link #currentProjectOverlay}
+     */
+    public ClassesPackagingTask( Overlay currentProjectOverlay )
+    {
+        this.currentProjectOverlay = currentProjectOverlay;
+    }
+
+    @Override
+    public void performPackaging( WarPackagingContext context )
+        throws MojoExecutionException
+    {
+        final File webappClassesDirectory = new File( context.getWebappDirectory(), CLASSES_PATH );
+        if ( !webappClassesDirectory.exists() )
+        {
+            webappClassesDirectory.mkdirs();
+        }
+
+        if ( context.getClassesDirectory().exists() && !context.getClassesDirectory().equals( webappClassesDirectory ) )
+        {
+            if ( context.archiveClasses() )
+            {
+                generateJarArchive( context );
+            }
+            else
+            {
+                final PathSet sources = getFilesToIncludes( context.getClassesDirectory(), null, null );
+                try
+                {
+                    copyFiles( currentProjectOverlay.getId(), context, context.getClassesDirectory(), sources,
+                               CLASSES_PATH, false );
+                }
+                catch ( IOException e )
+                {
+                    throw new MojoExecutionException( "Could not copy webapp classes ["
+                        + context.getClassesDirectory().getAbsolutePath() + "]", e );
+                }
+            }
+        }
+    }
+
+    /**
+     * @param context The warPackingContext.
+     * @throws MojoExecutionException In case of an error.
+     */
+    protected void generateJarArchive( WarPackagingContext context )
+        throws MojoExecutionException
+    {
+        MavenProject project = context.getProject();
+        ArtifactFactory factory = context.getArtifactFactory();
+        Artifact artifact =
+            factory.createBuildArtifact( project.getGroupId(), project.getArtifactId(), project.getVersion(), "jar" );
+        String archiveName;
+        try
+        {
+            archiveName = getArtifactFinalName( context, artifact );
+        }
+        catch ( InterpolationException e )
+        {
+            throw new MojoExecutionException( "Could not get the final name of the artifact [" + artifact.getGroupId()
+                + ":" + artifact.getArtifactId() + ":" + artifact.getVersion() + "]", e );
+        }
+        final String targetFilename = LIB_PATH + archiveName;
+
+        if ( context.getWebappStructure().registerFile( currentProjectOverlay.getId(), targetFilename ) )
+        {
+            context.addResource( targetFilename );
+
+            final File libDirectory = new File( context.getWebappDirectory(), LIB_PATH );
+            final File jarFile = new File( libDirectory, archiveName );
+            final ClassesPackager packager = new ClassesPackager();
+            packager.packageClasses( context.getClassesDirectory(), jarFile, context.getJarArchiver(),
+                                     context.getSession(), project, context.getArchive(),
+                                     context.getOutputTimestamp() );
+        }
+        else
+        {
+            context.getLog().warn( "Could not generate archive classes file [" + targetFilename
+                                       + "] has already been copied." );
+        }
+    }
+}
diff --git a/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/packaging/CopyUserManifestTask.java b/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/packaging/CopyUserManifestTask.java
new file mode 100644
index 000000000..217c18a2d
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/packaging/CopyUserManifestTask.java
@@ -0,0 +1,77 @@
+package org.apache.maven.plugins.war.packaging;
+
+/*
+ * 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.
+ */
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugin.logging.Log;
+import org.apache.maven.plugin.logging.SystemStreamLog;
+
+/**
+ * @author Haikal Saadh
+ *
+ */
+public class CopyUserManifestTask
+    extends AbstractWarPackagingTask
+{
+
+    /** Instance logger */
+    private Log log;
+
+    public Log getLog()
+    {
+        if ( log == null )
+        {
+            log = new SystemStreamLog();
+        }
+        return log;
+    }
+
+    public void setLog( Log log )
+    {
+        this.log = log;
+    }
+
+    public void performPackaging( WarPackagingContext context )
+        throws MojoExecutionException, MojoFailureException
+    {
+        File userManifest = context.getArchive().getManifestFile();
+        if ( userManifest != null )
+        {
+
+            try
+            {
+                getLog().info( "Copying manifest..." );
+                File metainfDir = new File( context.getWebappDirectory(), META_INF_PATH );
+                copyFile( context, userManifest, new File( metainfDir, "MANIFEST.MF" ), "META-INF/MANIFEST.MF", true );
+
+            }
+            catch ( IOException e )
+            {
+                throw new MojoExecutionException( "Error copying user manifest", e );
+            }
+        }
+
+    }
+
+}
diff --git a/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/packaging/OverlayPackagingTask.java b/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/packaging/OverlayPackagingTask.java
new file mode 100644
index 000000000..df7f2b400
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/packaging/OverlayPackagingTask.java
@@ -0,0 +1,157 @@
+package org.apache.maven.plugins.war.packaging;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugins.war.Overlay;
+import org.apache.maven.plugins.war.util.PathSet;
+import org.codehaus.plexus.util.FileUtils;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * Handles an overlay.
+ *
+ * @author Stephane Nicoll
+ */
+public class OverlayPackagingTask
+    extends AbstractWarPackagingTask
+{
+    private final Overlay overlay;
+
+    /**
+     * @param overlay {@link #overlay}
+     * @param currentProjectOverlay current overlay.
+     */
+    public OverlayPackagingTask( Overlay overlay, Overlay currentProjectOverlay )
+    {
+        if ( overlay == null )
+        {
+            throw new NullPointerException( "overlay could not be null." );
+        }
+        if ( overlay.equals( currentProjectOverlay ) )
+        {
+            throw new IllegalStateException( "Could not handle the current project with this task." );
+        }
+        this.overlay = overlay;
+    }
+
+    @Override
+    public void performPackaging( WarPackagingContext context )
+        throws MojoExecutionException
+    {
+        context.getLog().debug( "OverlayPackagingTask performPackaging overlay.getTargetPath() "
+                                    + overlay.getTargetPath() );
+        if ( overlay.shouldSkip() )
+        {
+            context.getLog().info( "Skipping overlay [" + overlay + "]" );
+        }
+        else
+        {
+            try
+            {
+                context.getLog().info( "Processing overlay [" + overlay + "]" );
+
+                // Step1: Extract if necessary
+                final File tmpDir = unpackOverlay( context, overlay );
+
+                // Step2: setup
+                final PathSet includes = getFilesToIncludes( tmpDir, overlay.getIncludes(), overlay.getExcludes() );
+
+                // Copy
+                if ( null == overlay.getTargetPath() )
+                {
+                    copyFiles( overlay.getId(), context, tmpDir, includes, overlay.isFiltered() );
+                }
+                else
+                {
+                    // overlay.getTargetPath() must ended with /
+                    // if not we add it
+                    String targetPath = overlay.getTargetPath();
+                    if ( !targetPath.endsWith( "/" ) )
+                    {
+                        targetPath = targetPath + "/";
+                    }
+                    copyFiles( overlay.getId(), context, tmpDir, includes, targetPath, overlay.isFiltered() );
+                }
+            }
+            catch ( IOException e )
+            {
+                throw new MojoExecutionException( "Failed to copy file for overlay [" + overlay + "]", e );
+            }
+        }
+    }
+
+    /**
+     * Unpacks the specified overlay.
+     * 
+     * Makes sure to skip the unpack process if the overlay has already been unpacked.
+     *
+     * @param context the packaging context
+     * @param overlay the overlay
+     * @return the directory containing the unpacked overlay
+     * @throws MojoExecutionException if an error occurred while unpacking the overlay
+     */
+    protected File unpackOverlay( WarPackagingContext context, Overlay overlay )
+        throws MojoExecutionException
+    {
+        final File tmpDir = getOverlayTempDirectory( context, overlay );
+
+        // TODO: not sure it's good, we should reuse the markers of the dependency plugin
+        if ( FileUtils.sizeOfDirectory( tmpDir ) == 0
+            || overlay.getArtifact().getFile().lastModified() > tmpDir.lastModified() )
+        {
+            doUnpack( context, overlay.getArtifact().getFile(), tmpDir );
+        }
+        else
+        {
+            context.getLog().debug( "Overlay [" + overlay + "] was already unpacked" );
+        }
+        return tmpDir;
+    }
+
+    /**
+     * Returns the directory to use to unpack the specified overlay.
+     *
+     * @param context the packaging context
+     * @param overlay the overlay
+     * @return the temp directory for the overlay
+     */
+    protected File getOverlayTempDirectory( WarPackagingContext context, Overlay overlay )
+    {
+        final File groupIdDir = new File( context.getOverlaysWorkDirectory(), overlay.getGroupId() );
+        if ( !groupIdDir.exists() )
+        {
+            groupIdDir.mkdir();
+        }
+        String directoryName = overlay.getArtifactId();
+        if ( overlay.getClassifier() != null )
+        {
+            directoryName = directoryName + "-" + overlay.getClassifier();
+        }
+        final File result = new File( groupIdDir, directoryName );
+        if ( !result.exists() )
+        {
+            result.mkdirs();
+        }
+        return result;
+    }
+}
diff --git a/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/packaging/WarPackagingContext.java b/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/packaging/WarPackagingContext.java
new file mode 100644
index 000000000..29336a234
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/packaging/WarPackagingContext.java
@@ -0,0 +1,253 @@
+package org.apache.maven.plugins.war.packaging;
+
+/*
+ * 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.
+ */
+
+import java.io.File;
+import java.util.List;
+
+import org.apache.maven.archiver.MavenArchiveConfiguration;
+import org.apache.maven.artifact.factory.ArtifactFactory;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.logging.Log;
+import org.apache.maven.plugins.war.util.WebappStructure;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.shared.filtering.MavenFileFilter;
+import org.apache.maven.shared.utils.io.FileUtils.FilterWrapper;
+import org.codehaus.plexus.archiver.jar.JarArchiver;
+import org.codehaus.plexus.archiver.manager.ArchiverManager;
+
+/**
+ * The packaging context.
+ *
+ * @author Stephane Nicoll
+ */
+public interface WarPackagingContext
+{
+    /**
+     * Returns the maven project.
+     *
+     * @return the project
+     */
+    MavenProject getProject();
+
+    /**
+     * Returns the webapp directory. Packaging tasks should use this directory to generate the webapp.
+     *
+     * @return the webapp directory
+     */
+    File getWebappDirectory();
+
+    /**
+     * Returns the main webapp source directory.
+     *
+     * @return the webapp source directory
+     */
+    File getWebappSourceDirectory();
+
+    /**
+     * Returns the webapp source includes.
+     *
+     * @return the webapp source includes
+     */
+    String[] getWebappSourceIncludes();
+
+    /**
+     * Returns {@code true} if empty directories should be includes, otherwise {@code false}
+     *
+     * @return {@code true} if empty directories should be includes, otherwise {@code false}
+     */
+    boolean isWebappSourceIncludeEmptyDirectories();
+
+    /**
+     * Returns the webapp source excludes.
+     *
+     * @return the webapp source excludes
+     */
+    String[] getWebappSourceExcludes();
+
+    /**
+     * Returns the directory holding generated classes.
+     *
+     * @return the classes directory
+     */
+    File getClassesDirectory();
+
+    /**
+     * Specify whether the classes resources should be archived in the <tt>WEB-INF/lib</tt> of the generated web app.
+     *
+     * @return true if the classes should be archived, false otherwise
+     */
+    boolean archiveClasses();
+
+    /**
+     * Returns the logger to use to output logging event.
+     *
+     * @return the logger
+     */
+    Log getLog();
+
+    /**
+     * Returns the directory to unpack dependent WARs into if needed.
+     *
+     * @return the overlays work directory
+     */
+    File getOverlaysWorkDirectory();
+
+    /**
+     * Returns the archiver manager to use.
+     *
+     * @return the archiver manager
+     */
+    ArchiverManager getArchiverManager();
+
+    /**
+     * The maven archive configuration to use.
+     *
+     * @return the maven archive configuration
+     */
+    MavenArchiveConfiguration getArchive();
+
+    /**
+     * Returns the Jar archiver needed for archiving classes directory into jar file under WEB-INF/lib.
+     *
+     * @return the jar archiver to user
+     */
+    JarArchiver getJarArchiver();
+
+    /**
+     * Returns the output file name mapping to use, if any. Returns <tt>null</tt> if no file name mapping is set.
+     *
+     * @return the output file name mapping or <tt>null</tt>
+     */
+    String getOutputFileNameMapping();
+
+    /**
+     * Returns the list of filter files to use.
+     *
+     * @return a list of filter files
+     */
+    List<String> getFilters();
+
+    /**
+     * Returns the {@link WebappStructure}.
+     *
+     * @return the webapp structure
+     */
+    WebappStructure getWebappStructure();
+
+    /**
+     * Returns the list of registered overlays for this session.
+     *
+     * @return the list of registered overlays, including the current project
+     */
+    List<String> getOwnerIds();
+
+    /**
+     * Returns the {@link MavenFileFilter} instance to use.
+     *
+     * @return the maven file filter to use
+     * @since 2.1-alpha-2
+     */
+    MavenFileFilter getMavenFileFilter();
+
+    /**
+     * @return {@link List} of {@link FilterWrapper}
+     * @since 2.1-alpha-2
+     */
+    List<FilterWrapper> getFilterWrappers();
+
+    /**
+     * Specify if the given <tt>fileName</tt> belongs to the list of extensions that must not be filtered
+     *
+     * @param fileName the name of file
+     * @return <tt>true</tt> if it should not be filtered, <tt>false</tt> otherwise
+     * @since 2.1-alpha-2
+     */
+    boolean isNonFilteredExtension( String fileName );
+
+    /**
+     * @return filtering deployment descriptor.
+     */
+    boolean isFilteringDeploymentDescriptors();
+
+    /**
+     * @return {@link ArtifactFactory}
+     */
+    ArtifactFactory getArtifactFactory();
+
+    /**
+     * Returns the Maven session.
+     *
+     * @return the Maven session
+     * @since 2.2
+     */
+    MavenSession getSession();
+
+    /**
+     * Returns the encoding to use for resources.
+     *
+     * @return the resource encoding
+     * @since 2.3
+     */
+    String getResourceEncoding();
+
+    /**
+     * @return to use jvmChmod rather than forking chmod cli
+     * @since 2.4
+     */
+    boolean isUseJvmChmod();
+
+    /**
+     * Returns the flag that switch on/off the missing web.xml validation
+     *
+     * @return failOnMissingWebXml
+     */
+    Boolean isFailOnMissingWebXml();
+
+    /**
+     * Add a live resource to the war.
+     * Used to keep track of existing resources and all copied files.
+     * All others are outdated and will be removed.
+     * This prevent calling <code>mvn clean</code> when resources are removed. 
+     * 
+     * @param resource the resource that is to me marked as not outdated
+     * @since 3.3.0
+     * @see #deleteOutdatedResources()
+     */
+    void addResource( String resource );
+
+    /**
+     * Delete outdated resources, ie resources that are found in the war but that were not added by the current
+     * packaging process, then are supposed to be content from a previous run.
+     * This prevent calling <code>mvn clean</code> when resources are removed.
+     * 
+     * @since 3.3.0
+     * @see #addResource
+     */
+    void deleteOutdatedResources();
+
+    /**
+     * Output timestamp for reproducible archive creation.
+     * 
+     * @return the output timestamp (may be null)
+     * @since 3.3.0
+     */
+    String getOutputTimestamp();
+}
diff --git a/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/packaging/WarPackagingTask.java b/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/packaging/WarPackagingTask.java
new file mode 100644
index 000000000..4260e1deb
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/packaging/WarPackagingTask.java
@@ -0,0 +1,45 @@
+package org.apache.maven.plugins.war.packaging;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+
+/**
+ * The base packaging task.
+ *
+ * @author Stephane Nicoll
+ */
+public interface WarPackagingTask
+{
+
+    /**
+     * Performs the packaging for the specified task.
+     * 
+     * The task is responsible to update the packaging context, namely with the files that have been copied.
+     *
+     * @param context the packaging context
+     * @throws MojoExecutionException if an error occurred
+     * @throws MojoFailureException if the project configuration is invalid
+     */
+    void performPackaging( WarPackagingContext context )
+        throws MojoExecutionException, MojoFailureException;
+
+}
diff --git a/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/packaging/WarProjectPackagingTask.java b/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/packaging/WarProjectPackagingTask.java
new file mode 100644
index 000000000..599370629
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/packaging/WarProjectPackagingTask.java
@@ -0,0 +1,381 @@
+package org.apache.maven.plugins.war.packaging;
+
+/*
+ * 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.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Objects;
+
+import org.apache.maven.model.Resource;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.war.Overlay;
+import org.apache.maven.plugins.war.util.PathSet;
+import org.apache.maven.shared.filtering.MavenFilteringException;
+import org.codehaus.plexus.util.DirectoryScanner;
+import org.codehaus.plexus.util.StringUtils;
+
+/**
+ * Handles the project own resources, that is: 
+ * <ul>
+ * <li>The list of web resources, if any</li>
+ * <li>The content of the webapp directory if it exists</li>
+ * <li>The custom deployment descriptor(s), if any</li>
+ * <li>The content of the classes directory if it exists</li>
+ * <li>The dependencies of the project</li>
+ * </ul>
+ *
+ * @author Stephane Nicoll
+ */
+public class WarProjectPackagingTask
+    extends AbstractWarPackagingTask
+{
+    private final Resource[] webResources;
+
+    private final File webXml;
+
+    private final File containerConfigXML;
+
+    private final String id;
+
+    private Overlay currentProjectOverlay;
+
+    /**
+     * @param webResources {@link #webResources}
+     * @param webXml {@link #webXml}
+     * @param containerConfigXml {@link #containerConfigXML}
+     * @param currentProjectOverlay {@link #currentProjectOverlay}
+     */
+    public WarProjectPackagingTask( Resource[] webResources, File webXml, File containerConfigXml,
+                                    Overlay currentProjectOverlay )
+    {
+        if ( webResources != null )
+        {
+            this.webResources = webResources;
+        }
+        else
+        {
+            this.webResources = new Resource[0];
+        }
+        this.webXml = webXml;
+        this.containerConfigXML = containerConfigXml;
+        this.currentProjectOverlay = currentProjectOverlay;
+        this.id = currentProjectOverlay.getId();
+    }
+
+    @Override
+    public void performPackaging( WarPackagingContext context )
+        throws MojoExecutionException, MojoFailureException
+    {
+        context.getLog().info( "Processing war project" );
+
+        // Prepare the INF directories
+        File webinfDir = new File( context.getWebappDirectory(), WEB_INF_PATH );
+        webinfDir.mkdirs();
+        File metainfDir = new File( context.getWebappDirectory(), META_INF_PATH );
+        metainfDir.mkdirs();
+
+        handleWebResources( context );
+
+        handleWebAppSourceDirectory( context );
+
+        // Debug mode: dump the path set for the current build
+        PathSet pathSet = context.getWebappStructure().getStructure( "currentBuild" );
+        context.getLog().debug( "Dump of the current build pathSet content -->" );
+        for ( String path : pathSet )
+        {
+            context.getLog().debug( path );
+        }
+        context.getLog().debug( "-- end of dump --" );
+
+        handleDeploymentDescriptors( context, webinfDir, metainfDir, context.isFailOnMissingWebXml() );
+
+        handleClassesDirectory( context );
+
+        handleArtifacts( context );
+
+        if ( !context.getWebappDirectory().mkdirs() )
+        {
+            context.deleteOutdatedResources();
+        }
+    }
+
+    /**
+     * Handles the web resources.
+     *
+     * @param context the packaging context
+     * @throws MojoExecutionException if a resource could not be copied
+     */
+    protected void handleWebResources( WarPackagingContext context )
+        throws MojoExecutionException
+    {
+        for ( Resource resource : webResources )
+        {
+
+            // MWAR-246
+            if ( resource.getDirectory() == null )
+            {
+                throw new MojoExecutionException( "The <directory> tag is missing from the <resource> tag." );
+            }
+
+            if ( !( new File( resource.getDirectory() ) ).isAbsolute() )
+            {
+                resource.setDirectory( context.getProject().getBasedir() + File.separator + resource.getDirectory() );
+            }
+
+            // Make sure that the resource directory is not the same as the webappDirectory
+            if ( !resource.getDirectory().equals( context.getWebappDirectory().getPath() ) )
+            {
+
+                try
+                {
+                    copyResources( context, resource );
+                }
+                catch ( IOException e )
+                {
+                    throw new MojoExecutionException( "Could not copy resource [" + resource.getDirectory() + "]", e );
+                }
+            }
+        }
+    }
+
+    /**
+     * Handles the webapp sources.
+     *
+     * @param context the packaging context
+     * @throws MojoExecutionException if the sources could not be copied
+     */
+    protected void handleWebAppSourceDirectory( WarPackagingContext context )
+        throws MojoExecutionException
+    {
+        // CHECKSTYLE_OFF: LineLength
+        if ( !context.getWebappSourceDirectory().exists() )
+        {
+            context.getLog().debug( "webapp sources directory does not exist - skipping." );
+        }
+        else if ( !context.getWebappSourceDirectory().getAbsolutePath().equals( context.getWebappDirectory().getPath() ) )
+        {
+            context.getLog().info( "Copying webapp resources [" + context.getWebappSourceDirectory() + "]" );
+            final PathSet sources =
+                getFilesToIncludes( context.getWebappSourceDirectory(), context.getWebappSourceIncludes(),
+                                    context.getWebappSourceExcludes(), context.isWebappSourceIncludeEmptyDirectories() );
+
+            try
+            {
+                copyFiles( id, context, context.getWebappSourceDirectory(), sources, false );
+            }
+            catch ( IOException e )
+            {
+                throw new MojoExecutionException( "Could not copy webapp sources ["
+                    + context.getWebappDirectory().getAbsolutePath() + "]", e );
+            }
+        }
+        // CHECKSTYLE_ON: LineLength
+    }
+
+    /**
+     * Handles the webapp artifacts.
+     *
+     * @param context the packaging context
+     * @throws MojoExecutionException if the artifacts could not be packaged
+     */
+    protected void handleArtifacts( WarPackagingContext context )
+        throws MojoExecutionException
+    {
+        ArtifactsPackagingTask task =
+            new ArtifactsPackagingTask( context.getProject().getArtifacts(), currentProjectOverlay );
+        task.performPackaging( context );
+    }
+
+    /**
+     * Handles the webapp classes.
+     *
+     * @param context the packaging context
+     * @throws MojoExecutionException if the classes could not be packaged
+     */
+    protected void handleClassesDirectory( WarPackagingContext context )
+        throws MojoExecutionException
+    {
+        ClassesPackagingTask task = new ClassesPackagingTask( currentProjectOverlay );
+        task.performPackaging( context );
+    }
+
+    /**
+     * Handles the deployment descriptors, if specified. Note that the behavior here is slightly different since the
+     * customized entry always win, even if an overlay has already packaged a web.xml previously.
+     *
+     * @param context the packaging context
+     * @param webinfDir the web-inf directory
+     * @param metainfDir the meta-inf directory
+     * @param failOnMissingWebXml if build should fail if web.xml is not found
+     * @throws MojoFailureException if the web.xml is specified but does not exist and failOnMissingWebXml is true
+     * @throws MojoExecutionException if an error occurred while copying the descriptors
+     */
+    protected void handleDeploymentDescriptors( WarPackagingContext context, File webinfDir, File metainfDir,
+                                                Boolean failOnMissingWebXml )
+        throws MojoFailureException, MojoExecutionException
+    {
+        try
+        {
+            if ( webXml != null && StringUtils.isNotEmpty( webXml.getName() ) )
+            {
+                if ( !webXml.exists()
+                        && ( failOnMissingWebXml == null || Boolean.TRUE.equals( failOnMissingWebXml ) ) )
+                {
+                    throw new MojoFailureException( "The specified web.xml file '" + webXml + "' does not exist" );
+                }
+
+                // Making sure that it won't get overlayed
+                context.getWebappStructure().registerFileForced( id, WEB_INF_PATH + "/web.xml" );
+
+                if ( context.isFilteringDeploymentDescriptors() )
+                {
+                    context.getMavenFileFilter().copyFile( webXml, new File( webinfDir, "web.xml" ), true,
+                                                           context.getFilterWrappers(), getEncoding( webXml ) );
+                }
+                else
+                {
+                    copyFile( context, webXml, new File( webinfDir, "web.xml" ), "WEB-INF/web.xml", true );
+                }
+            }
+            else
+            {
+                // the webXml can be the default one
+                File defaultWebXml = new File( context.getWebappSourceDirectory(), WEB_INF_PATH + "/web.xml" );
+                // if exists we can filter it
+                if ( defaultWebXml.exists() && context.isFilteringDeploymentDescriptors() )
+                {
+                    context.getWebappStructure().registerFile( id, WEB_INF_PATH + "/web.xml" );
+                    context.getMavenFileFilter().copyFile( defaultWebXml, new File( webinfDir, "web.xml" ), true,
+                                                           context.getFilterWrappers(), getEncoding( defaultWebXml ) );
+                }
+            }
+
+            if ( containerConfigXML != null && StringUtils.isNotEmpty( containerConfigXML.getName() ) )
+            {
+                String xmlFileName = containerConfigXML.getName();
+
+                context.getWebappStructure().registerFileForced( id, META_INF_PATH + "/" + xmlFileName );
+
+                if ( context.isFilteringDeploymentDescriptors() )
+                {
+                    context.getMavenFileFilter().copyFile( containerConfigXML, new File( metainfDir, xmlFileName ),
+                                                           true, context.getFilterWrappers(),
+                                                           getEncoding( containerConfigXML ) );
+                }
+                else
+                {
+                    copyFile( context, containerConfigXML, new File( metainfDir, xmlFileName ), "META-INF/"
+                        + xmlFileName, true );
+                }
+            }
+        }
+        catch ( IOException e )
+        {
+            if ( failOnMissingWebXml == null || Boolean.TRUE.equals( failOnMissingWebXml ) )
+            {
+                throw new MojoExecutionException( "Failed to copy deployment descriptor", e );
+            }
+        }
+        catch ( MavenFilteringException e )
+        {
+            throw new MojoExecutionException( "Failed to copy deployment descriptor", e );
+        }
+    }
+
+    /**
+     * Copies webapp webResources from the specified directory.
+     *
+     * @param context the WAR packaging context to use
+     * @param resource the resource to copy
+     * @throws IOException if an error occurred while copying the resources
+     * @throws MojoExecutionException if an error occurred while retrieving the filter properties
+     */
+    public void copyResources( WarPackagingContext context, Resource resource )
+        throws IOException, MojoExecutionException
+    {
+        if ( !context.getWebappDirectory().exists() )
+        {
+            context.getLog().warn( "Not copying webapp webResources [" + resource.getDirectory()
+                                       + "]: webapp directory [" + context.getWebappDirectory().getAbsolutePath()
+                                       + "] does not exist!" );
+        }
+
+        context.getLog().info( "Copying webapp webResources [" + resource.getDirectory() + "] to ["
+                                   + context.getWebappDirectory().getAbsolutePath() + "]" );
+        String[] fileNames = getFilesToCopy( resource );
+        for ( String fileName : fileNames )
+        {
+            String targetFileName = fileName;
+            if ( resource.getTargetPath() != null )
+            {
+                // TODO make sure this thing is 100% safe
+                // MWAR-129 if targetPath is only a dot <targetPath>.</targetPath> or ./
+                // and the Resource is in a part of the warSourceDirectory the file from sources will override this
+                // that's we don't have to add the targetPath yep not nice but works
+                if ( !Objects.equals( ".", resource.getTargetPath() )
+                    && !Objects.equals( "./", resource.getTargetPath() ) )
+                {
+                    targetFileName = resource.getTargetPath() + File.separator + targetFileName;
+                }
+            }
+            if ( resource.isFiltering() && !context.isNonFilteredExtension( fileName ) )
+            {
+                copyFilteredFile( id, context, new File( resource.getDirectory(), fileName ), targetFileName );
+            }
+            else
+            {
+                copyFile( id, context, new File( resource.getDirectory(), fileName ), targetFileName );
+            }
+        }
+    }
+
+    /**
+     * Returns a list of filenames that should be copied over to the destination directory.
+     *
+     * @param resource the resource to be scanned
+     * @return the array of filenames, relative to the sourceDir
+     */
+    private String[] getFilesToCopy( Resource resource )
+    {
+        // CHECKSTYLE_OFF: LineLength
+        DirectoryScanner scanner = new DirectoryScanner();
+        scanner.setBasedir( resource.getDirectory() );
+        if ( resource.getIncludes() != null && !resource.getIncludes().isEmpty() )
+        {
+            scanner.setIncludes( resource.getIncludes().toArray( new String[resource.getIncludes().size()] ) );
+        }
+        else
+        {
+            scanner.setIncludes( DEFAULT_INCLUDES );
+        }
+        if ( resource.getExcludes() != null && !resource.getExcludes().isEmpty() )
+        {
+            scanner.setExcludes( resource.getExcludes().toArray( new String[resource.getExcludes().size()] ) );
+        }
+
+        scanner.addDefaultExcludes();
+
+        scanner.scan();
+
+        return scanner.getIncludedFiles();
+        // CHECKSTYLE_ON: LineLength
+    }
+}
diff --git a/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/util/ClassesPackager.java b/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/util/ClassesPackager.java
new file mode 100644
index 000000000..2b14617cf
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/util/ClassesPackager.java
@@ -0,0 +1,88 @@
+package org.apache.maven.plugins.war.util;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.archiver.MavenArchiveConfiguration;
+import org.apache.maven.archiver.MavenArchiver;
+import org.apache.maven.artifact.DependencyResolutionRequiredException;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugins.war.packaging.AbstractWarPackagingTask;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.archiver.ArchiverException;
+import org.codehaus.plexus.archiver.jar.JarArchiver;
+import org.codehaus.plexus.archiver.jar.ManifestException;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * Packages the content of the classes directory.
+ *
+ * @author Stephane Nicoll
+ */
+public class ClassesPackager
+{
+
+    /**
+     * Package the classes
+     *
+     * @param classesDirectory the classes directory
+     * @param targetFile the target file
+     * @param jarArchiver the jar archiver to use
+     * @param session the current session
+     * @param project the related project
+     * @param archiveConfiguration the archive configuration to use
+     * @param outputTimestamp the output timestamp for reproducibility
+     * @throws MojoExecutionException if an error occurred while creating the archive
+     */
+    public void packageClasses( File classesDirectory, File targetFile, JarArchiver jarArchiver, MavenSession session,
+                                MavenProject project, MavenArchiveConfiguration archiveConfiguration,
+                                String outputTimestamp )
+        throws MojoExecutionException
+    {
+
+        try
+        {
+            final MavenArchiver archiver = new MavenArchiver();
+            archiver.setArchiver( jarArchiver );
+            archiver.setOutputFile( targetFile );
+            archiver.setCreatedBy( "Maven WAR Plugin", "org.apache.maven.plugins", "maven-war-plugin" );
+            archiver.configureReproducible( outputTimestamp );
+            archiver.getArchiver().addDirectory( classesDirectory );
+            archiver.createArchive( session, project, archiveConfiguration );
+        }
+        catch ( ArchiverException | ManifestException | IOException | DependencyResolutionRequiredException e )
+        {
+            throw new MojoExecutionException( "Could not create classes archive", e );
+        }
+    }
+
+    /**
+     * Returns the classes directory from the specified webapp directory.
+     *
+     * @param webappDirectory the webapp directory
+     * @return the classes directory of the specified webapp directory
+     */
+    public File getClassesDirectory( File webappDirectory )
+    {
+        return new File( webappDirectory, AbstractWarPackagingTask.CLASSES_PATH );
+    }
+}
diff --git a/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/util/DependencyInfo.java b/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/util/DependencyInfo.java
new file mode 100644
index 000000000..f38ab060a
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/util/DependencyInfo.java
@@ -0,0 +1,103 @@
+package org.apache.maven.plugins.war.util;
+
+/*
+ * 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.
+ */
+
+import java.util.Objects;
+
+import org.apache.maven.model.Dependency;
+
+/**
+ * Holds a dependency and packaging information.
+ *
+ * @author Stephane Nicoll
+ */
+public class DependencyInfo
+{
+
+    private final Dependency dependency;
+
+    private String targetFileName;
+
+    /**
+     * Creates a new instance.
+     *
+     * @param dependency the dependency
+     */
+    public DependencyInfo( Dependency dependency )
+    {
+        this.dependency = dependency;
+    }
+
+    /**
+     * Returns the dependency.
+     *
+     * @return the dependency
+     */
+    public Dependency getDependency()
+    {
+        return dependency;
+    }
+
+    /**
+     * Returns the target filename of the dependency. If no target file name is associated, returns <tt>null</tt>.
+     *
+     * @return the target file name or <tt>null</tt>
+     */
+    public String getTargetFileName()
+    {
+        return targetFileName;
+    }
+
+    /**
+     * Sets the target file name.
+     *
+     * @param targetFileName the target file name
+     */
+    public void setTargetFileName( String targetFileName )
+    {
+        this.targetFileName = targetFileName;
+    }
+
+    @Override
+    public boolean equals( Object o )
+    {
+        if ( this == o )
+        {
+            return true;
+        }
+        if ( o == null || getClass() != o.getClass() )
+        {
+            return false;
+        }
+
+        DependencyInfo that = (DependencyInfo) o;
+
+        return Objects.equals( dependency, that.dependency );
+    }
+
+    @Override
+    public int hashCode()
+    {
+        int result;
+        result = ( dependency != null ? dependency.hashCode() : 0 );
+        result = 31 * result + ( targetFileName != null ? targetFileName.hashCode() : 0 );
+        return result;
+    }
+}
diff --git a/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/util/PathSet.java b/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/util/PathSet.java
new file mode 100644
index 000000000..23da7b377
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/util/PathSet.java
@@ -0,0 +1,264 @@
+package org.apache.maven.plugins.war.util;
+
+/*
+ * 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.
+ */
+
+import org.codehaus.plexus.util.DirectoryScanner;
+
+import java.io.File;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+/**
+ * Set of file's paths.
+ * 
+ * The class extends functionality of a "normal" set of strings by a process of the paths normalization. All paths are
+ * converted to unix form (slashes) and they don't start with starting /.
+ *
+ * @author Piotr Tabor
+ */
+
+public class PathSet
+    implements Iterable<String>
+{
+    private static final String SEPARATOR = "/";
+    private static final char SEPARATOR_CHAR = SEPARATOR.charAt( 0 );
+    /**
+     * Set of normalized paths
+     */
+    private Set<String> pathsSet = new LinkedHashSet<>();
+
+    static String normalizeSubPath( String path )
+    {
+        if ( path.isEmpty() )
+        {
+            return path;
+        }
+        String cleanPath = path.replaceAll( "[\\\\]+", SEPARATOR )
+                .replaceAll( "[/]+" , SEPARATOR );
+        cleanPath = cleanPath.charAt( 0 ) == SEPARATOR_CHAR ? cleanPath.substring( 1 ) : cleanPath;
+        if ( cleanPath.isEmpty() )
+        {
+            return cleanPath;
+        }
+        if ( cleanPath.charAt( cleanPath.length() - 1 ) == SEPARATOR_CHAR )
+        {
+            return cleanPath.substring( 0, cleanPath.length() - 1 );
+        }
+        return cleanPath;
+    }
+
+    /*-------------------- Business interface ------------------------------*/
+
+    /**
+     * Creates an empty paths set
+     */
+    public PathSet()
+    {
+        /* Empty default constructor */
+    }
+
+    /**
+     * Creates paths set and normalizate and adds all 'paths'. The source 'paths' will not be changed
+     *
+     * @param paths to be added
+     */
+    public PathSet( Collection<String> paths )
+    {
+        addAll( paths );
+    }
+
+    /**
+     * Creates paths set and normalizate and adds all 'paths'. The source 'paths' will not be changed
+     *
+     * @param paths to be added
+     */
+    public PathSet( String[] paths )
+    {
+        addAll( paths );
+    }
+
+    /**
+     * Normalizes and adds given path to the set.
+     *
+     * @param path to be added
+     */
+    public void add( String path )
+    {
+        pathsSet.add( normalizeSubPath( path ) );
+    }
+
+    /**
+     * Normalizes and adds given paths (collection of strings) to the set. The source collection will not be changed
+     *
+     * @param paths - collection of strings to be added
+     * @param prefix added to all given paths
+     */
+    public void addAll( Collection<String> paths, String prefix )
+    {
+        for ( String val : paths )
+        {
+            add( prefix + SEPARATOR +  val );
+        }
+    }
+
+    /**
+     * Normalizes and adds given paths to the set. The source collection will not be changed
+     *
+     * @param paths to be added
+     * @param prefix added to all given paths
+     */
+    public void addAll( String[] paths, String prefix )
+    {
+        for ( String val : paths )
+        {
+            add( prefix + SEPARATOR + val );
+        }
+    }
+
+    /**
+     * Adds given paths to the set. The source collection will not be changed
+     *
+     * @param paths to be added
+     * @param prefix added to all given paths
+     */
+    public void addAll( PathSet paths, String prefix )
+    {
+        for ( String path : paths )
+        {
+            add( prefix + SEPARATOR + path );
+        }
+    }
+
+    /**
+     * Normalizes and adds given paths (collection of strings) to the set. The source collection will not be changed
+     *
+     * @param paths - collection of strings to be added
+     */
+    public void addAll( Collection<String> paths )
+    {
+        addAll( paths, "" );
+    }
+
+    /**
+     * Normalizes and adds given paths to the set. The source collection will not be changed
+     *
+     * @param paths to be added
+     */
+    public void addAll( String[] paths )
+    {
+        addAll( paths, "" );
+    }
+
+    /**
+     * Adds given paths to the set. The source collection will not be changed
+     *
+     * @param paths to be added
+     */
+    public void addAll( PathSet paths )
+    {
+        addAll( paths, "" );
+    }
+
+    /**
+     * Checks if the set constains given path. The path is normalized before check.
+     *
+     * @param path we are looking for in the set.
+     * @return information if the set constains the path.
+     */
+    public boolean contains( String path )
+    {
+        return pathsSet.contains( normalizeSubPath( path ) );
+    }
+
+    /**
+     * Removes the specified path if it exists.
+     *
+     * @param path the path to remove
+     * @return true if the path was removed, false if it did not existed
+     */
+    boolean remove( String path )
+    {
+        return pathsSet.remove( normalizeSubPath( path ) );
+    }
+
+    /**
+     * Returns iterator of normalized paths (strings)
+     *
+     * @return iterator of normalized paths (strings)
+     */
+    @Override
+    public Iterator<String> iterator()
+    {
+        return pathsSet.iterator();
+    }
+
+    /**
+     * @return {@link #pathsSet}
+     */
+    public Collection<String> paths()
+    {
+        return pathsSet;
+    }
+
+    /**
+     * Adds given prefix to all paths in the set.
+     * 
+     * The prefix should be ended by '/'. The generated paths are normalized.
+     *
+     * @param prefix to be added to all items
+     */
+    public void addPrefix( String prefix )
+    {
+        final Set<String> newSet = new HashSet<>();
+        for ( String path : pathsSet )
+        {
+            newSet.add( normalizeSubPath( prefix + path ) );
+        }
+        pathsSet = newSet;
+    }
+
+    /**
+     * Returns count of the paths in the set
+     *
+     * @return count of the paths in the set
+     */
+    public int size()
+    {
+        return pathsSet.size();
+    }
+
+    /**
+     * Adds to the set all files in the given directory
+     *
+     * @param directory that will be searched for file's paths to add
+     * @param prefix to be added to all found files
+     */
+    public void addAllFilesInDirectory( File directory, String prefix )
+    {
+        DirectoryScanner scanner = new DirectoryScanner();
+        scanner.setBasedir( directory );
+        scanner.scan();
+        addAll( scanner.getIncludedFiles(), prefix );
+    }
+
+}
diff --git a/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/util/WarUtils.java b/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/util/WarUtils.java
new file mode 100644
index 000000000..19dbb7980
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/util/WarUtils.java
@@ -0,0 +1,105 @@
+package org.apache.maven.plugins.war.util;
+
+/*
+ * 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.
+ */
+
+import java.util.Objects;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.project.MavenProject;
+
+/**
+ * @author Stephane Nicoll
+ */
+public class WarUtils
+{
+
+    /**
+     * @param project {@link MavenProject}
+     * @param dependency {@link Dependency}
+     * @return {@link Artifact}
+     */
+    public static Artifact getArtifact( MavenProject project, Dependency dependency )
+    {
+        for ( Artifact artifact : project.getArtifacts() )
+        {
+            if ( artifact.getGroupId().equals( dependency.getGroupId() )
+                && artifact.getArtifactId().equals( dependency.getArtifactId() )
+                && artifact.getType().equals( dependency.getType() ) )
+            {
+                if ( artifact.getClassifier() == null && dependency.getClassifier() == null )
+                {
+                    return artifact;
+                }
+                else if ( dependency.getClassifier() != null
+                    && dependency.getClassifier().equals( artifact.getClassifier() ) )
+                {
+                    return artifact;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * @param artifact {@link Artifact}
+     * @param dependency {@link Dependency}
+     * @return is related or not.
+     */
+    public static boolean isRelated( Artifact artifact, Dependency dependency )
+    {
+        if ( artifact == null || dependency == null )
+        {
+            return false;
+        }
+
+        if ( !Objects.equals( artifact.getGroupId(), dependency.getGroupId() ) )
+        {
+            return false;
+        }
+        if ( !Objects.equals( artifact.getArtifactId(), dependency.getArtifactId() ) )
+        {
+            return false;
+        }
+        if ( Objects.equals( artifact.getVersion(), dependency.getVersion() ) )
+        {
+            return false;
+        }
+        if ( Objects.equals( artifact.getType(), dependency.getType() ) )
+        {
+            return false;
+        }
+        if ( Objects.equals( artifact.getClassifier(), dependency.getClassifier() ) )
+        {
+            return false;
+        }
+        if ( Objects.equals( artifact.getScope(), dependency.getScope() ) )
+        {
+            return false;
+        }
+        if ( artifact.isOptional() != dependency.isOptional() )
+        {
+            return false;
+        }
+
+        return true;
+    }
+
+}
diff --git a/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/util/WebappStructure.java b/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/util/WebappStructure.java
new file mode 100644
index 000000000..9d116508a
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/main/java/org/apache/maven/plugins/war/util/WebappStructure.java
@@ -0,0 +1,391 @@
+package org.apache.maven.plugins.war.util;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.model.Dependency;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Represents the structure of a web application composed of multiple overlays. Each overlay is registered within this
+ * structure with the set of files it holds.
+ * 
+ * Note that this structure is persisted to disk at each invocation to store which owner holds which path (file).
+ *
+ * @author Stephane Nicoll
+ */
+public class WebappStructure
+{
+
+    private Map<String, PathSet> registeredFiles;
+
+    private List<DependencyInfo> dependenciesInfo;
+
+    private transient PathSet allFiles = new PathSet();
+
+    /**
+     * Creates a new empty instance.
+     *
+     * @param dependencies the dependencies of the project
+     */
+    public WebappStructure( List<Dependency> dependencies )
+    {
+        this.dependenciesInfo = createDependenciesInfoList( dependencies );
+        this.registeredFiles = new HashMap<>();
+    }
+
+    /**
+     * Returns the list of {@link DependencyInfo} for the project.
+     *
+     * @return the dependencies information of the project
+     */
+    public List<DependencyInfo> getDependenciesInfo()
+    {
+        return dependenciesInfo;
+    }
+
+    /**
+     * Returns the dependencies of the project.
+     *
+     * @return the dependencies of the project
+     */
+    public List<Dependency> getDependencies()
+    {
+        final List<Dependency> result = new ArrayList<>();
+        if ( dependenciesInfo == null )
+        {
+            return result;
+        }
+        for ( DependencyInfo dependencyInfo : dependenciesInfo )
+        {
+            result.add( dependencyInfo.getDependency() );
+        }
+        return result;
+    }
+
+    /**
+     * Specify if the specified <tt>path</tt> is registered or not.
+     *
+     * @param path the relative path from the webapp root directory
+     * @return true if the path is registered, false otherwise
+     */
+    public boolean isRegistered( String path )
+    {
+        return getFullStructure().contains( path );
+
+    }
+
+    /**
+     * Registers the specified path for the specified owner. Returns <tt>true</tt> if the path is not already
+     * registered, <tt>false</tt> otherwise.
+     *
+     * @param id the owner of the path
+     * @param path the relative path from the webapp root directory
+     * @return true if the file was registered successfully
+     */
+    public boolean registerFile( String id, String path )
+    {
+        if ( !isRegistered( path ) )
+        {
+            doRegister( id, path );
+            return true;
+        }
+        else
+        {
+            return false;
+        }
+    }
+
+    /**
+     * Forces the registration of the specified path for the specified owner. If the file is not registered yet, a
+     * simple registration is performed. If the file already exists, the owner changes to the specified one.
+     * <p>
+     * Beware that the semantic of the return boolean is different than the one from
+     * {@link #registerFile(String, String)}; returns <tt>true</tt> if an owner replacement was made and <tt>false</tt>
+     * if the file was simply registered for the first time.</p>
+     *
+     * @param id the owner of the path
+     * @param path the relative path from the webapp root directory
+     * @return false if the file did not exist, true if the owner was replaced
+     */
+    public boolean registerFileForced( String id, String path )
+    {
+        if ( !isRegistered( path ) )
+        {
+            doRegister( id, path );
+            return false;
+        }
+        else
+        {
+            // Force the switch to the new owner
+            getStructure( getOwner( path ) ).remove( path );
+            getStructure( id ).add( path );
+            return true;
+        }
+
+    }
+
+    /**
+     * Registers the specified path for the specified owner. Invokes the <tt>callback</tt> with the result of the
+     * registration.
+     *
+     * @param id the owner of the path
+     * @param path the relative path from the webapp root directory
+     * @param callback the callback to invoke with the result of the registration
+     * @throws IOException if the callback invocation throws an IOException
+     */
+    public void registerFile( String id, String path, RegistrationCallback callback )
+        throws IOException
+    {
+
+        // If the file is already in the current structure, rejects it with the current owner
+        if ( isRegistered( path ) )
+        {
+            callback.refused( id, path, getOwner( path ) );
+        }
+        else
+        {
+            doRegister( id, path );
+            // This is a new file
+            if ( getOwner( path ) == null )
+            {
+                callback.registered( id, path );
+
+            } // The file already belonged to this owner
+            else if ( getOwner( path ).equals( id ) )
+            {
+                callback.alreadyRegistered( id, path );
+            } // The file belongs to another owner and it's known currently
+            else if ( getOwners().contains( getOwner( path ) ) )
+            {
+                callback.superseded( id, path, getOwner( path ) );
+            } // The file belongs to another owner and it's unknown
+            else
+            {
+                callback.supersededUnknownOwner( id, path, getOwner( path ) );
+            }
+        }
+    }
+
+    /**
+     * Returns the owner of the specified <tt>path</tt>. If the file is not registered, returns <tt>null</tt>
+     *
+     * @param path the relative path from the webapp root directory
+     * @return the owner or <tt>null</tt>.
+     */
+    public String getOwner( String path )
+    {
+        if ( !isRegistered( path ) )
+        {
+            return null;
+        }
+        else
+        {
+            for ( final String owner : registeredFiles.keySet() )
+            {
+                final PathSet structure = getStructure( owner );
+                if ( structure.contains( path ) )
+                {
+                    return owner;
+                }
+
+            }
+            throw new IllegalStateException( "Should not happen, path [" + path
+                + "] is flagged as being registered but was not found." );
+        }
+
+    }
+
+    /**
+     * Returns the owners.
+     *
+     * @return the list of owners
+     */
+    public Set<String> getOwners()
+    {
+        return registeredFiles.keySet();
+    }
+
+    /**
+     * Returns all paths that have been registered so far.
+     *
+     * @return all registered path
+     */
+    public PathSet getFullStructure()
+    {
+        return allFiles;
+    }
+
+    /**
+     * Returns the list of registered files for the specified owner.
+     *
+     * @param id the owner
+     * @return the list of files registered for that owner
+     */
+    public PathSet getStructure( String id )
+    {
+        PathSet pathSet = registeredFiles.get( id );
+        if ( pathSet == null )
+        {
+            pathSet = new PathSet();
+            registeredFiles.put( id, pathSet );
+        }
+        return pathSet;
+    }
+
+    
+
+    /**
+     * Registers the target file name for the specified artifact.
+     *
+     * @param artifact the artifact
+     * @param targetFileName the target file name
+     */
+    public void registerTargetFileName( Artifact artifact, String targetFileName )
+    {
+        if ( dependenciesInfo != null )
+        {
+            for ( DependencyInfo dependencyInfo : dependenciesInfo )
+            {
+                if ( WarUtils.isRelated( artifact, dependencyInfo.getDependency() ) )
+                {
+                    dependencyInfo.setTargetFileName( targetFileName );
+                }
+            }
+        }
+    }
+
+    // Private helpers
+
+    private void doRegister( String id, String path )
+    {
+        getFullStructure().add( path );
+        getStructure( id ).add( path );
+    }
+
+    private List<DependencyInfo> createDependenciesInfoList( List<Dependency> dependencies )
+    {
+        if ( dependencies == null )
+        {
+            return Collections.emptyList();
+        }
+        final List<DependencyInfo> result = new ArrayList<>();
+        for ( Dependency dependency : dependencies )
+        {
+            result.add( new DependencyInfo( dependency ) );
+        }
+        return result;
+    }
+
+    private Object readResolve()
+    {
+        // the full structure should be resolved so let's rebuild it
+        this.allFiles = new PathSet();
+        for ( PathSet pathSet : registeredFiles.values() )
+        {
+            this.allFiles.addAll( pathSet );
+        }
+        return this;
+    }
+
+    /**
+     * Callback interface to handle events related to filepath registration in the webapp.
+     */
+    public interface RegistrationCallback
+    {
+
+        /**
+         * Called if the <tt>targetFilename</tt> for the specified <tt>ownerId</tt> has been registered successfully.
+         * 
+         * This means that the <tt>targetFilename</tt> was unknown and has been registered successfully.
+         *
+         * @param ownerId the ownerId
+         * @param targetFilename the relative path according to the root of the webapp
+         * @throws IOException if an error occurred while handling this event
+         */
+        void registered( String ownerId, String targetFilename )
+            throws IOException;
+
+        /**
+         * Called if the <tt>targetFilename</tt> for the specified <tt>ownerId</tt> has already been registered.
+         * 
+         * This means that the <tt>targetFilename</tt> was known and belongs to the specified owner.
+         *
+         * @param ownerId the ownerId
+         * @param targetFilename the relative path according to the root of the webapp
+         * @throws IOException if an error occurred while handling this event
+         */
+        void alreadyRegistered( String ownerId, String targetFilename )
+            throws IOException;
+
+        /**
+         * <p>
+         * Called if the registration of the <tt>targetFilename</tt> for the specified <tt>ownerId</tt> has been refused
+         * since the path already belongs to the <tt>actualOwnerId</tt>.
+         * </p> 
+         * This means that the <tt>targetFilename</tt> was known and does not belong to the specified owner.
+         *
+         * @param ownerId the ownerId
+         * @param targetFilename the relative path according to the root of the webapp
+         * @param actualOwnerId the actual owner
+         * @throws IOException if an error occurred while handling this event
+         */
+        void refused( String ownerId, String targetFilename, String actualOwnerId )
+            throws IOException;
+
+        /**
+         * Called if the <tt>targetFilename</tt> for the specified <tt>ownerId</tt> has been registered successfully by
+         * superseding a <tt>deprecatedOwnerId</tt>, that is the previous owner of the file.
+         * 
+         * This means that the <tt>targetFilename</tt> was known but for another owner. This usually happens after a
+         * project's configuration change. As a result, the file has been registered successfully to the new owner.
+         *
+         * @param ownerId the ownerId
+         * @param targetFilename the relative path according to the root of the webapp
+         * @param deprecatedOwnerId the previous owner that does not exist anymore
+         * @throws IOException if an error occurred while handling this event
+         */
+        void superseded( String ownerId, String targetFilename, String deprecatedOwnerId )
+            throws IOException;
+
+        /**
+         * Called if the <tt>targetFilename</tt> for the specified <tt>ownerId</tt> has been registered successfully by
+         * superseding a <tt>unknownOwnerId</tt>, that is an owner that does not exist anymore in the current project.
+         * 
+         * This means that the <tt>targetFilename</tt> was known but for an owner that does not exist anymore. Hence the
+         * file has been registered successfully to the new owner.
+         *
+         * @param ownerId the ownerId
+         * @param targetFilename the relative path according to the root of the webapp
+         * @param unknownOwnerId the previous owner that does not exist anymore
+         * @throws IOException if an error occurred while handling this event
+         */
+        void supersededUnknownOwner( String ownerId, String targetFilename, String unknownOwnerId )
+            throws IOException;
+    }
+
+}
diff --git a/Java-base/maven-war-plugin/src/src/main/resources-filtered/META-INF/plexus/components.xml b/Java-base/maven-war-plugin/src/src/main/resources-filtered/META-INF/plexus/components.xml
new file mode 100644
index 000000000..85adcb528
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/main/resources-filtered/META-INF/plexus/components.xml
@@ -0,0 +1,89 @@
+<?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.
+-->
+
+<component-set>
+  <components>
+    <!--
+     | WAR
+     |-->
+    <component>
+      <role>org.apache.maven.artifact.handler.ArtifactHandler</role>
+      <role-hint>war</role-hint>
+      <implementation>org.apache.maven.artifact.handler.DefaultArtifactHandler</implementation>
+      <configuration>
+        <type>war</type>
+        <includesDependencies>true</includesDependencies>
+        <language>java</language>
+        <addedToClasspath>false</addedToClasspath>
+      </configuration>
+    </component>
+
+    <!--
+      | Defining the phases with their appropriate plugins
+      ! and versions which will be executed during the 'default'
+      ! life cycle.
+    -->
+    <!--
+     | WAR
+     |-->
+    <component>
+      <role>org.apache.maven.lifecycle.mapping.LifecycleMapping</role>
+      <role-hint>war</role-hint>
+      <implementation>org.apache.maven.lifecycle.mapping.DefaultLifecycleMapping</implementation>
+      <configuration>
+        <lifecycles>
+          <lifecycle>
+            <id>default</id>
+            <!-- START SNIPPET: war-lifecycle -->
+            <phases>
+              <process-resources>
+                org.apache.maven.plugins:maven-resources-plugin:3.0.2:resources
+              </process-resources>
+              <compile>
+                org.apache.maven.plugins:maven-compiler-plugin:3.7.0:compile
+              </compile>
+              <process-test-resources>
+                org.apache.maven.plugins:maven-resources-plugin:3.0.2:testResources
+              </process-test-resources>
+              <test-compile>
+                org.apache.maven.plugins:maven-compiler-plugin:3.7.0:testCompile
+              </test-compile>
+              <test>
+                org.apache.maven.plugins:maven-surefire-plugin:2.19.1:test
+              </test>
+              <package>
+                org.apache.maven.plugins:maven-war-plugin:${project.version}:war
+              </package>
+              <install>
+                org.apache.maven.plugins:maven-install-plugin:2.5.2:install
+              </install>
+              <deploy>
+                org.apache.maven.plugins:maven-deploy-plugin:2.8.2:deploy
+              </deploy>
+            </phases>
+            <!-- END SNIPPET: war-lifecycle -->
+          </lifecycle>
+        </lifecycles>
+      </configuration>
+    </component>
+
+  </components>
+</component-set>
diff --git a/Java-base/maven-war-plugin/src/src/site/apt/examples/adding-filtering-webresources.apt.vm b/Java-base/maven-war-plugin/src/src/site/apt/examples/adding-filtering-webresources.apt.vm
new file mode 100644
index 000000000..56f97baeb
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/site/apt/examples/adding-filtering-webresources.apt.vm
@@ -0,0 +1,407 @@
+ ------
+ Adding and Filtering External Web Resources
+ ------
+ Pete Marvin King
+ Dennis Lundberg
+ ------
+ 2012-09-28
+ ------
+
+~~ 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.
+
+~~ NOTE: For help with the syntax of this file, see:
+~~ http://maven.apache.org/doxia/references/apt-format.html
+
+Adding and Filtering External Web Resources
+
+ The default resource directory for all Maven projects is <<<src/main/resources>>> which
+ will end up in <<<target/classes>>> and in <<<WEB-INF/classes>>> in the WAR. The directory
+ structure will be preserved in the process.
+
+ The WAR Plugin is also capable of including resources not found in the default resource
+ directory through the <<<webResources>>> parameter.
+
+*Adding web resources
+
++-------+
+<project>
+  ...
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-war-plugin</artifactId>
+        <version>${project.version}</version>
+        <configuration>
+          <webResources>
+            <resource>
+              <!-- this is relative to the pom.xml directory -->
+              <directory>resource2</directory>
+            </resource>
+          </webResources>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  ...
+</project>
++-------+
+
+ Using our sample project in the {{{../usage.html}usage section}} with an added external resource, like this:
+
+----------
+ .
+ |-- pom.xml
+ |-- resource2
+ |   |-- external-resource.jpg
+ |   `-- image2
+ |       `-- external-resource2.jpg
+ `-- src
+     `-- main
+         |-- java
+         |   `-- com
+         |       `-- example
+         |           `-- projects
+         |               `-- SampleAction.java
+         |-- resources
+         |   `-- images
+         |       `-- sampleimage.jpg
+         `-- webapp
+             |-- WEB-INF
+             |   `-- web.xml
+             |-- index.jsp
+             `-- jsp
+                 `-- websource.jsp
+----------
+
+ would end up in the WAR as:
+
+----------
+documentedproject-1.0-SNAPSHOT.war
+ |-- META-INF
+ |   |-- MANIFEST.MF
+ |   `-- maven
+ |       `-- com.example.projects
+ |           `-- documentedproject
+ |               |-- pom.properties
+ |               `-- pom.xml
+ |-- WEB-INF
+ |   |-- classes
+ |   |   |-- com
+ |   |   |   `-- example
+ |   |   |       `-- projects
+ |   |   |           `-- SampleAction.class
+ |   |   `-- images
+ |   |       `-- sampleimage.jpg
+ |   `-- web.xml
+ |-- external-resource.jpg
+ |-- image2
+ |   `-- external-resource2.jpg
+ |-- index.jsp
+ `-- jsp
+     `-- websource.jsp
+----------
+
+ <<<external-resource2.jpg>>> and <<<image2>>> are copied to the root of the WAR, preserving the
+ directory structure.
+
+*Configuring web Resources
+
+ <<<webResources>>> is a list of resources. All options of resource are supported.
+
+ A web resource
+
+  * can have includes/excludes
+
+  * can be filtered
+
+  * is not limited to the default destination - the root of the WAR
+
+**Includes/Excludes
+
+ To include all jpgs in the WAR we can add the following to our POM configuration from above:
+
++----------+
+        ...
+        <configuration>
+          <webResources>
+            <resource>
+              <!-- this is relative to the pom.xml directory -->
+              <directory>resource2</directory>
+              <!-- the list has a default value of ** -->
+              <includes>
+                <include>**/*.jpg</include>
+              </includes>
+            </resource>
+          </webResources>
+        </configuration>
+        ...
++----------+
+
+ To exclude the <<<image2>>> directory from the WAR add this:
+
++----------+
+        ...
+        <configuration>
+          <webResources>
+            <resource>
+              <!-- this is relative to the pom.xml directory -->
+              <directory>resource2</directory>
+              <!-- there's no default value for this -->
+              <excludes>
+                <exclude>**/image2</exclude>
+              </excludes>
+            </resource>
+          </webResources>
+        </configuration>
+        ...
++----------+
+
+ Be careful when mixing includes and excludes, excludes will have a higher priority.
+ Includes can not override excludes if a resource matches both.
+
+ Having this configuration will exclude all jpgs from the WAR:
+
++----------+
+        ...
+        <configuration>
+          <webResources>
+            <resource>
+              <!-- this is relative to the pom.xml directory -->
+              <directory>resource2/</directory>
+              <!-- the list has a default value of ** -->
+              <includes>
+                <include>image2/*.jpg</include>
+              </includes>
+              <!-- there's no default value for this -->
+              <excludes>
+                <exclude>**/*.jpg</exclude>
+              </excludes>
+            </resource>
+          </webResources>
+        </configuration>
+        ...
++----------+
+
+ Here's another example of how to specify include and exclude patterns:
+
++----------+
+        ...
+        <configuration>
+          <webResources>
+            <resource>
+              <!-- this is relative to the pom.xml directory -->
+              <directory>resource2</directory>
+              <!-- the default value is ** -->
+              <includes>
+                <include>**/pattern1</include>
+                <include>*pattern2</include>
+              </includes>
+              <!-- there's no default value for this -->
+              <excludes>
+                <exclude>*pattern3/pattern3</exclude>
+                <exclude>pattern4/pattern4</exclude>
+              </excludes>
+            </resource>
+          </webResources>
+        </configuration>
+        ...
++----------+
+
+**Filtering
+
+  Using our example above, we can also configure filters for our resources.
+  We will add a hypothetical <<<configurations>>> directory to our project:
+
+----------
+ .
+ |-- configurations
+ |   |-- config.cfg
+ |   `-- properties
+ |       `-- config.prop
+ |-- pom.xml
+ |-- resource2
+ |   |-- external-resource.jpg
+ |   `-- image2
+ |       `-- external-resource2.jpg
+ `-- src
+     `-- main
+         |-- java
+         |   `-- com
+         |       `-- example
+         |           `-- projects
+         |               `-- SampleAction.java
+         |-- resources
+         |   `-- images
+         |       `-- sampleimage.jpg
+         `-- webapp
+             |-- WEB-INF
+             |   `-- web.xml
+             |-- index.jsp
+             `-- jsp
+                 `-- websource.jsp
+----------
+
+  To prevent corrupting your binary files when filtering is enabled, you can configure a list of file extensions that
+  will not be filtered.
+
++----------+
+        ...
+        <configuration>
+          <!-- the default value is the filter list under build -->
+          <!-- specifying a filter will override the filter list under build -->
+          <filters>
+            <filter>properties/config.prop</filter>
+          </filters>
+          <nonFilteredFileExtensions>
+            <!-- default value contains jpg,jpeg,gif,bmp,png -->
+            <nonFilteredFileExtension>pdf</nonFilteredFileExtension>
+          </nonFilteredFileExtensions>
+          <webResources>
+            <resource>
+              <directory>resource2</directory>
+              <!-- it's not a good idea to filter binary files -->
+              <filtering>false</filtering>
+            </resource>
+            <resource>
+              <directory>configurations</directory>
+              <!-- enable filtering -->
+              <filtering>true</filtering>
+              <excludes>
+                <exclude>**/properties</exclude>
+              </excludes>
+            </resource>
+          </webResources>
+        </configuration>
+        ...
++----------+
+
+*** <<<config.prop>>>
+
++----------+
+interpolated_property=some_config_value
++----------+
+
+*** <<<config.cfg>>>
+
++----------+
+<another_ioc_container>
+   <configuration>${interpolated_property}</configuration>
+</another_ioc_container>
++----------+
+
+ The resulting WAR would be:
+
+----------
+documentedproject-1.0-SNAPSHOT.war
+ |-- META-INF
+ |   |-- MANIFEST.MF
+ |   `-- maven
+ |       `-- com.example.projects
+ |           `-- documentedproject
+ |               |-- pom.properties
+ |               `-- pom.xml
+ |-- WEB-INF
+ |   |-- classes
+ |   |   |-- com
+ |   |   |   `-- example
+ |   |   |       `-- projects
+ |   |   |           `-- SampleAction.class
+ |   |   `-- images
+ |   |       `-- sampleimage.jpg
+ |   `-- web.xml
+ |-- config.cfg
+ |-- external-resource.jpg
+ |-- image2
+ |   `-- external-resource2.jpg
+ |-- index.jsp
+ `-- jsp
+     `-- websource.jsp
+----------
+
+ and the content of <<<config.cfg>>> would be:
+
++----------+
+<another_ioc_container>
+   <configuration>some_config_value</configuration>
+</another_ioc_container>
++----------+
+
+  <<Note:>> In versions 2.2 and earlier of this plugin the platform encoding was
+  used when filtering resources. Depending on what that encoding was you could
+  end up with scrambled characters after filtering. Starting with version 2.3
+  this plugin respects the property <<<project.build.sourceEncoding>>> when
+  filtering resources. One notable exception to this is that <<<.xml>>> files
+  are filtered using the encoding specified inside the xml-file itself.
+
+
+**Overriding the default destination directory
+
+ By default web resources are copied to the root of the WAR, as shown in the previous example.
+ To override the default destination directory, specify the target path.
+
++----------+
+        ...
+        <configuration>
+          <webResources>
+            <resource>
+              ...
+            </resource>
+            <resource>
+              <directory>configurations</directory>
+              <!-- override the destination directory for this resource -->
+              <targetPath>WEB-INF</targetPath>
+              <!-- enable filtering -->
+              <filtering>true</filtering>
+              <excludes>
+                <exclude>**/properties</exclude>
+              </excludes>
+            </resource>
+          </webResources>
+        </configuration>
+        ...
++----------+
+
+ Using the sample project the resulting WAR would look like this:
+
+----------
+documentedproject-1.0-SNAPSHOT.war
+ |-- META-INF
+ |   |-- MANIFEST.MF
+ |   `-- maven
+ |       `-- com.example.projects
+ |           `-- documentedproject
+ |               |-- pom.properties
+ |               `-- pom.xml
+ |-- WEB-INF
+ |   |-- classes
+ |   |   |-- com
+ |   |   |   `-- example
+ |   |   |       `-- projects
+ |   |   |           `-- SampleAction.class
+ |   |   `-- images
+ |   |       `-- sampleimage.jpg
+ |   |-- config.cfg
+ |   `-- web.xml
+ |-- external-resource.jpg
+ |-- image2
+ |   `-- external-resource2.jpg
+ |-- index.jsp
+ `-- jsp
+     `-- websource.jsp
+----------
diff --git a/Java-base/maven-war-plugin/src/src/site/apt/examples/file-name-mapping.apt b/Java-base/maven-war-plugin/src/src/site/apt/examples/file-name-mapping.apt
new file mode 100644
index 000000000..0e96b41b2
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/site/apt/examples/file-name-mapping.apt
@@ -0,0 +1,60 @@
+ ------
+ Using File Name Mapping
+ ------
+ Stephane Nicoll
+ Dennis Lundberg
+ ------
+ 2010-05-24
+
+~~ 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.
+
+~~ NOTE: For help with the syntax of this file, see:
+~~ http://maven.apache.org/doxia/references/apt-format.html
+
+Using File Name Mapping
+
+ It might be necessary to customize the file name of libraries and TLDs. By default, those resources are stored
+ using the following pattern:
+
++-----
+@{artifactId}@-@{version}@.@{extension}@
++-----
+
+ If the artifact has a classifier the default pattern is of course:
+
++-----
+@{artifactId}@-@{version}@-@{classifier}@.@{extension}@
++-----
+
+ The <<<outputFileNameMapping>>> parameter allows you to give a custom pattern. Each token defined in the
+ pattern will be replaced with a value from the current artifact. You can use any property of Artifact and
+ ArtifactHandler as a token. There is also a special token named <<<dashClassifier?>>> that can be used, since 2.1.
+ It will add the string "-yourclassifier" if and only if the artifact has a classifier.
+
+ For instance, to store the libraries and TLDs without version numbers or classifiers, use the following pattern:
+
++-----
+@{artifactId}@.@{extension}@
++-----
+
+ To store the libraries and TLDs without version numbers but with classifiers
+ (if they exist), use the following pattern:
+
++-----
+@{artifactId}@@{dashClassifier?}@.@{extension}@
++-----
diff --git a/Java-base/maven-war-plugin/src/src/site/apt/examples/including-excluding-files-from-war.apt.vm b/Java-base/maven-war-plugin/src/src/site/apt/examples/including-excluding-files-from-war.apt.vm
new file mode 100644
index 000000000..74a4e71da
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/site/apt/examples/including-excluding-files-from-war.apt.vm
@@ -0,0 +1,94 @@
+  ------
+  Including and Excluding Files From the WAR
+  ------
+  Dennis Lundberg
+  ------
+  2011-11-21
+  ------
+
+~~ 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.
+
+~~ NOTE: For help with the syntax of this file, see:
+~~ http://maven.apache.org/doxia/references/apt-format.html
+
+Including and Excluding Files From the WAR
+
+
+  It is possible to include or exclude certain files from the WAR file, by using
+  the <<<\<packagingIncludes\>>>> and <<<\<packagingExcludes\>>>> configuration
+  parameters. They each take a comma-separated list of Ant file set patterns.
+  You can use wildcards such as <<<**>>> to indicate multiple directories and
+  <<<*>>> to indicate an optional part of a file or directory name.
+  
+  Here is an example where we exclude all JAR files from <<<WEB-INF/lib>>>:
+
++-----------------+
+<project>
+  ...
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-war-plugin</artifactId>
+        <version>${project.version}</version>
+        <configuration>
+          <packagingExcludes>WEB-INF/lib/*.jar</packagingExcludes>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  ...
+</project>
++-----------------+
+
+  Sometimes even such wildcards are not enough. In these cases you can use
+  regular expressions with the <<<%regex[]>>> syntax. Here is a real life use
+  case in which this is used. In this example we want to exclude any
+  commons-logging and log4j JARs, but we do not want to exclude the
+  log4j-over-slf4j JAR. So we want to exclude <<<log4j-\<version\>.jar>>> but
+  keep the <<<log4j-over-slf4j-\<version\>.jar>>>.
+
++-----------------+
+<project>
+  ...
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-war-plugin</artifactId>
+        <version>${project.version}</version>
+        <configuration>
+          <!--
+            Exclude JCL and LOG4J since all logging should go through SLF4J.
+            Note that we're excluding log4j-<version>.jar but keeping
+            log4j-over-slf4j-<version>.jar
+          -->
+          <packagingExcludes>
+            WEB-INF/lib/commons-logging-*.jar,
+            %regex[WEB-INF/lib/log4j-(?!over-slf4j).*.jar]
+          </packagingExcludes>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  ...
+</project>
++-----------------+
+
+  If you have more real life examples of using regular expressions, we'd like to
+  know about them. Please file an issue in
+  {{{../issue-tracking.html}our issue tracker}} with your configuration, so we
+  can expand this page.
diff --git a/Java-base/maven-war-plugin/src/src/site/apt/examples/rapid-testing-jetty6-plugin.apt b/Java-base/maven-war-plugin/src/src/site/apt/examples/rapid-testing-jetty6-plugin.apt
new file mode 100644
index 000000000..a500a933b
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/site/apt/examples/rapid-testing-jetty6-plugin.apt
@@ -0,0 +1,75 @@
+ ------
+ Rapid Testing Using the Jetty Plugin
+ ------
+ Pete Marvin King
+ ------
+ 2008-08-03
+ ------
+
+~~ 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.
+
+~~ NOTE: For help with the syntax of this file, see:
+~~ http://maven.apache.org/doxia/references/apt-format.html
+
+Rapid Testing Using the Jetty Plugin
+
+ Normally, testing a web application involves compiling Java sources, creating a WAR and
+ deploying it to a web container.
+
+ Using the Jetty Plugin enables you to quickly test your web application by skipping
+ the last two steps. By default the Jetty Plugin scans <<<target/classes>>> for
+ any changes in your Java sources and <<<src/main/webapp>>> for changes to your web sources.
+ The Jetty Plugin will automatically reload the modified classes and web sources.
+
+ To use the Jetty Plugin just add the following in your <<<pom.xml>>>:
+
++-----------------+
+<project>
+  ...
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.mortbay.jetty</groupId>
+        <artifactId>maven-jetty-plugin</artifactId>
+        <version>6.1.10</version>
+        <configuration>
+          <scanIntervalSeconds>10</scanIntervalSeconds>
+          <connectors>
+            <connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
+              <port>8080</port>
+              <maxIdleTime>60000</maxIdleTime>
+            </connector>
+          </connectors>
+        </configuration>
+      </plugin>
+      ...
+    </plugins>
+  </build>
+  ...
+</project>
++-----------------+
+
+ Then start Jetty:
+
+-----------------
+  mvn jetty:run
+-----------------
+
+ The command will block with Jetty listening on port 8080.
+
+ Check the {{{http://docs.codehaus.org/display/JETTY/Maven+Jetty+Plugin}Jetty Plugin documentation}} for more details.
diff --git a/Java-base/maven-war-plugin/src/src/site/apt/examples/skinny-wars.apt.vm b/Java-base/maven-war-plugin/src/src/site/apt/examples/skinny-wars.apt.vm
new file mode 100644
index 000000000..f530dbdde
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/site/apt/examples/skinny-wars.apt.vm
@@ -0,0 +1,112 @@
+ ------
+ Creating Skinny WARs
+ ------
+ Mike Perham
+ Karl-Heinz Marbaise
+ ------
+ 2014-10-01
+ ------
+
+~~ 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.
+
+~~ NOTE: For help with the syntax of this file, see:
+~~ http://maven.apache.org/doxia/references/apt-format.html
+
+Creating Skinny WARs
+
+ In a typical J2EE environment, a WAR is packaged within an EAR for deployment.  The
+ WAR can contain all its dependent JARs in <<<WEB-INF/lib>>> but then the EAR can quickly grow
+ very large if there are multiple WARs, due to the presence of duplicate JARs.  Instead
+ the J2EE specification allows WARs to reference external JARs packaged within the EAR
+ via the <<<Class-Path>>> setting in their <<<MANIFEST.MF>>>.
+
+ The Maven EAR Plugin has direct support for creating skinny wars which simply
+ means to {{{http://maven.apache.org/plugins/maven-ear-plugin/examples/skinny-wars.html}configure the maven-ear-plugin}}
+ accordingly.
+
+ You need to change the EAR project's <<<pom.xml>>> to package those dependent JARs in the EAR.
+ Notice that we package everything into a <<<lib/>>> directory within the EAR.  This is
+ just my own personal preference to distinguish between J2EE modules (which will
+ be packaged in the root of the EAR) and Java libraries (which are packaged in <<<lib/>>>).
+
++-----------------+
+<project>
+  ...
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-ear-plugin</artifactId>
+        <version>2.9.1</version>
+        <configuration>
+          <defaultLibBundleDir>lib/</defaultLibBundleDir>
+          <skinnyWars>true</skinnyWars>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  ...
+</project>
++-----------------+
+
+ Now the painful part.  Your EAR project's <<<pom.xml>>> needs to list every dependency that the WAR has.
+ This is because Maven assumes fat WARs and does not include transitive dependencies
+ of WARs within the EAR.
+
++-----------------+
+<project>
+  ....
+  <dependencies>
+    <dependency>
+      <groupId>com.acme</groupId>
+      <artifactId>shared-jar</artifactId>
+      <version>1.0.0</version>
+    </dependency>
+    <dependency>
+      <groupId>com.acme</groupId>
+      <artifactId>war1</artifactId>
+      <version>1.0.0</version>
+      <type>war</type>
+    </dependency>
+    <dependency>
+      <groupId>com.acme</groupId>
+      <artifactId>war2</artifactId>
+      <version>1.0.0</version>
+      <type>war</type>
+    </dependency>
+  </dependencies>
+  ...
+</project>
++-----------------+
+
+ Your EAR will contain something like this:
+
+-----------------
+ .
+ |-- META-INF
+ |   `-- application.xml
+ |-- lib
+ |   `-- shared-jar-1.0.0.jar
+ |-- war1-1.0.0.war
+ `-- war2-1.0.0.war
+-----------------
+
+
+* Alternatives
+
+ Our users have submitted alternatives to the above recipe on
+ {{{http://docs.codehaus.org/display/MAVENUSER/Solving+the+Skinny+Wars+problem}the Wiki}}.
diff --git a/Java-base/maven-war-plugin/src/src/site/apt/examples/war-manifest-guide.apt.vm b/Java-base/maven-war-plugin/src/src/site/apt/examples/war-manifest-guide.apt.vm
new file mode 100644
index 000000000..a3aadb302
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/site/apt/examples/war-manifest-guide.apt.vm
@@ -0,0 +1,102 @@
+ ------
+ WAR Manifest Customization
+ ------
+ Pete Marvin King
+ ------
+ 2008-08-03
+ ------
+
+~~ 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.
+
+~~ NOTE: For help with the syntax of this file, see:
+~~ http://maven.apache.org/doxia/references/apt-format.html
+
+WAR Manifest Customization
+
+ The manifest can be customized by configuring the WAR Plugin's archiver. For full information on the different
+ configuration options available check the documentation for
+ {{{http://maven.apache.org/shared/maven-archiver/index.html}Maven Archiver}}.
+
+
+*Generating a manifest classpath
+
+  Generating a manifest classpath for a WAR is similar to for a JAR, but there are a couple of slight differences since
+  you normally don't want a JAR in both the manifest classpath and the <<<WEB-INF/lib>>> directory.  Customize the WAR
+  Plugin's archiver:
+
++--------------------+
+<project>
+  ...
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-war-plugin</artifactId>
+        <version>${project.version}</version>
+        <configuration>
+          <archive>
+            <manifest>
+              <addClasspath>true</addClasspath>
+            </manifest>
+          </archive>
+        </configuration>
+      </plugin>
+      ...
+    </plugins>
+  </build>
+  ...
+</project>
++--------------------+
+
+  Now, you can control which dependencies are included in <<<WEB-INF/lib>>> and in the manifest classpath by following
+  these examples.  Maven will follow the transitive dependency tree until it gets to artifacts scoped as "provided".
+
+  <<Note:>> No way is shown how to include a dependency in <<<WEB-INF/lib>>> but not in the manifest classpath.
+
++--------------------+
+<project>
+  ...
+  <dependencies>
+    <dependency>
+      <groupId>org.foo</groupId>
+      <artifactId>bar-jar1</artifactId>
+      <version>${pom.version}</version>
+      <optional>true</optional>
+      <!-- goes in manifest classpath, but not included in WEB-INF/lib -->
+    </dependency>
+    <dependency>
+      <groupId>org.foo</groupId>
+      <artifactId>bar-jar2</artifactId>
+      <version>${pom.version}</version>
+      <!-- goes in manifest classpath, AND included in WEB-INF/lib -->
+    </dependency>
+    <dependency>
+      <groupId>org.foo</groupId>
+      <artifactId>bar-jar3</artifactId>
+      <version>${pom.version}</version>
+      <scope>provided</scope>
+      <!-- excluded from manifest classpath, and excluded from WEB-INF/lib -->
+    </dependency>
+    ...
+  </dependencies>
+  ...
+</project>
++--------------------+
+
+  Check the {{{http://maven.apache.org/guides/mini/guide-manifest.html}Guide to Working with Manifests}} for more
+  examples.
diff --git a/Java-base/maven-war-plugin/src/src/site/apt/index.apt.vm b/Java-base/maven-war-plugin/src/src/site/apt/index.apt.vm
new file mode 100644
index 000000000..edcc5c5c5
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/site/apt/index.apt.vm
@@ -0,0 +1,98 @@
+ ------
+ Introduction
+ ------
+ Pete Marvin King
+ ------
+ 2013-07-22
+ ------
+
+~~ 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.
+
+~~ NOTE: For help with the syntax of this file, see:
+~~ http://maven.apache.org/doxia/references/apt-format.html
+
+${project.name}
+
+ The WAR Plugin is responsible for collecting all artifact dependencies, classes
+ and resources of the web application and packaging them into a web application 
+ archive.
+
+* Goals Overview
+
+ * {{{./war-mojo.html}war:war}} is the default goal invoked during the 
+   <<<package>>> phase for projects with a packaging type of <<<war>>>. 
+   It builds a WAR file.
+
+ * {{{./exploded-mojo.html}war:exploded}} is generally used to speed up 
+   testing during the developement phase by creating an exploded webapp 
+   in a specified directory.
+
+ * {{{./inplace-mojo.html}war:inplace}} another variation of <<<war:explode>>> 
+   where the webapp is instead generated in the web application source directory, 
+   which is <<<src/main/webapp>>> by default.
+
+ []
+
+* Usage
+
+  General instructions on how to use the WAR Plugin can be found on the 
+  {{{./usage.html}usage page}}. Some more specific use cases are described in the 
+  examples given below. To share common resources across multiple web applications, 
+  see the documentation about using {{{./overlays.html}overlays}}.
+
+  In case you still have questions regarding the plugin's usage, please have a look at the 
+  {{{./faq.html}FAQ}} and feel free to contact the {{{./mailing-lists.html}user mailing list}}. 
+  The posts to the mailing list are archived and could already contain the answer to your 
+  question as part of an older thread. Hence, it is also worth browsing/searching
+  the {{{./mailing-lists.html}mail archive}}.
+
+  If you feel like the plugin is missing a feature or has a defect, you can fill a 
+  feature request or bug report in our {{{./issue-management.html}issue tracker}}. 
+  When creating a new issue, please provide a comprehensive description of your
+  concern. Especially for fixing bugs it is crucial that the developers can 
+  reproduce your problem. For this reason, entire debug logs, POMs or most 
+  preferably little demo projects attached to the issue are very much appreciated.
+  Of course, patches are welcome, too. Contributors can check out the project from 
+  our {{{./scm.html}source repository}} and will find supplementary 
+  information in the
+  {{{/guides/development/guide-helping.html}guide to helping with Maven}}.
+
+* Examples
+
+  To provide you with better understanding on some usages of the Maven WAR Plugin,
+  you can take a look into the following examples:
+
+ * {{{./examples/adding-filtering-webresources.html}Adding and Filtering External Web Resources}}
+
+ * {{{./examples/war-manifest-guide.html}WAR Manifest Customization}}
+
+ * {{{./examples/rapid-testing-jetty6-plugin.html}Rapid Testing the Jetty Plugin}}
+
+ * {{{./examples/skinny-wars.html}Creating Skinny WARs}}
+
+ * {{{./examples/including-excluding-files-from-war.html}Including and Excluding Files From the WAR}}
+
+ * {{{./examples/file-name-mapping.html}Using File Name Mapping}}
+
+ []
+
+* Related links
+
+  * {{{/guides/mini/guide-archive-configuration.html}Exclusion of Maven Descriptors}}
+
+  []
diff --git a/Java-base/maven-war-plugin/src/src/site/apt/overlays.apt.vm b/Java-base/maven-war-plugin/src/src/site/apt/overlays.apt.vm
new file mode 100644
index 000000000..741a80e59
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/site/apt/overlays.apt.vm
@@ -0,0 +1,393 @@
+ ------
+ Overlays
+ ------
+ Pete Marvin King
+ Stephane Nicoll
+ Dennis Lundberg
+ ------
+ 2010-08-14
+
+~~ 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.
+
+~~ NOTE: For help with the syntax of this file, see:
+~~ http://maven.apache.org/doxia/references/apt-format.html
+
+Overlays
+
+ Overlays are used to share common resources across multiple web applications.
+ The dependencies of a WAR project are collected in <<<WEB-INF/lib>>>, except for WAR
+ artifacts which are overlayed on the WAR project itself.
+
+
+* Overlays at a glance
+
+  To demonstrate, given this structure for the project <<<documentedproject>>>:
+
+-----------------
+ |-- pom.xml
+ `-- src
+     `-- main
+         |-- java
+         |   `-- com
+         |       `-- example
+         |           `-- projects
+         |               `-- SampleAction.java
+         |-- resources
+         |   |-- images
+         |   |   `-- sampleimage.jpg
+         |   `-- sampleresource
+         `-- webapp
+             |-- WEB-INF
+             |   `-- web.xml
+             |-- index.jsp
+             `-- jsp
+                 `-- websource.jsp
+-----------------
+
+ The project depends on another WAR artifact, <<<documentedprojectdependency-1.0-SNAPSHOT.war>>>,
+ which is declared as a dependency in the project's <<<pom.xml>>>:
+
++-----------------+
+<project>
+  ...
+  <dependencies>
+    <dependency>
+      <groupId>com.example.projects</groupId>
+      <artifactId>documentedprojectdependency</artifactId>
+      <version>1.0-SNAPSHOT</version>
+      <type>war</type>
+      <scope>runtime</scope>
+    </dependency>
+    ...
+  </dependencies>
+  ...
+</project>
++-----------------+
+
+  The structure for the <<<documentedprojectdependency>>> WAR file looks like this:
+
+-----------------
+documentedprojectdependency-1.0-SNAPSHOT.war
+ |-- META-INF
+ |   |-- MANIFEST.MF
+ |   `-- maven
+ |       `-- com.example.projects
+ |           `-- documentedprojectdependency
+ |               |-- pom.properties
+ |               `-- pom.xml
+ |-- WEB-INF
+ |   |-- classes
+ |   |   |-- com
+ |   |   |   `-- example
+ |   |   |       `-- projects
+ |   |   |           `-- SampleActionDependency.class
+ |   |   `-- images
+ |   |       `-- sampleimage-dependency.jpg
+ |   `-- web.xml
+ `-- index-dependency.jsp
+-----------------
+
+ The resulting WAR would end up like this:
+
+-----------------
+ |-- META-INF
+ |   |-- MANIFEST.MF
+ |   `-- maven
+ |       `-- com.example.projects
+ |           `-- documentedproject
+ |               |-- pom.properties
+ |               `-- pom.xml
+ |-- WEB-INF
+ |   |-- classes
+ |   |   |-- com
+ |   |   |   `-- example
+ |   |   |       `-- projects
+ |   |   |           |-- SampleAction.class
+ |   |   |           `-- SampleActionDependency.class
+ |   |   `-- images
+ |   |       |-- sampleimage-dependency.jpg
+ |   |       `-- sampleimage.jpg
+ |   `-- web.xml
+ |-- index-dependency.jsp
+ |-- index.jsp
+ `-- jsp
+     `-- websource.jsp
+-----------------
+
+  The <<<web.xml>>> file above comes from <<<documentedproject>>>.
+
+
+* Overlay types
+
+  The WAR Plugin handles both <<war>> and <<zip>> artifacts as overlays. However, for backward compatibility reasons, zip
+  overlays are handled only if they are defined explicitly in the plugin's configuration.
+
+
+* Configuring Overlays
+
+  In previous versions of the WAR Plugin, no configuration was necessary. This is still the
+  case if you are happy with the default settings. However, if you need more control, read on!
+
+  The <<<\<{overlay}\>>>> element can have the following child elements:
+
+  * <<id>> - the id of the overlay. If none is provided, the WAR Plugin will
+  generate one.
+
+  * <<groupId>> - the groupId of the overlay artifact you want to configure.
+
+  * <<artifactId>> - the artifactId of the overlay artifact you want to
+  configure.
+
+  * <<type>> - the type of the overlay artifact you want to
+  configure. Default value is: <<<war>>>.
+
+  * <<classifier>> - the classifier of the overlay artifact you want to
+  configure if multiple artifacts matches the groupId/artifactId.
+
+  * <<includes>> - the files to include. By default, all files are included.
+
+  * <<excludes>> - the files to exclude. By default, the <<<META-INF/MANIFEST.MF>>> file
+  is excluded.
+
+  * <<targetPath>> - the target relative path in the webapp structure, which is only
+  available for overlays of type <<<war>>>. By default, the content of the overlay is added in the root
+  structure of the webapp.
+
+  * <<skip>> - set to <<<true>>> to skip this overlay. Default value is: <<<false>>>.
+
+  * <<filtered>> - whether to apply filtering to this overlay. Default value is <<<false>>>.
+
+  []
+
+  For instance, to exclude the <<<sampleimage-dependency.jpg>>> of our
+  <<<documentedprojectdependency>>> <<<war>>> overlay above:
+
++-----------------+
+<project>
+  ...
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-war-plugin</artifactId>
+        <version>${project.version}</version>
+        <configuration>
+          <overlays>
+            <overlay>
+              <groupId>com.example.projects</groupId>
+              <artifactId>documentedprojectdependency</artifactId>
+              <excludes>
+                <exclude>WEB-INF/classes/images/sampleimage-dependency.jpg</exclude>
+              </excludes>
+            </overlay>
+          </overlays>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  ...
+</project>
++-----------------+
+
+
+* Overlays packaging
+
+  Overlays are applied with a first-win strategy (hence if a file has been copied by
+  one overlay, it won't be copied by another). Overlays are applied in the order in which
+  they are defined in the <<<\<overlays\>>>> configuration. If no configuration is provided,
+  the order in which the dependencies are defined in the POM is used (warning: this is not
+  deterministic, especially if you have overlays as transitive dependencies). In case of
+  a mixed situation (e.g. configured overlays and non-configured overlays), non-configured
+  overlays are applied after configured overlays.
+
+  By default, the source of the project (a.k.a the current build) is added first (e.g.
+  before any overlay is applied). The current build is defined as a special overlay
+  with no <<<groupId>>>, <<<artifactId>>>. If overlays need to be applied first, simply
+  configure the current build after those overlays.
+
+  For instance, if <<<my-webapp>>> from the <<<com.example.projects>>> group is a dependency
+  of the project and needs to be applied before the project's own source, do as follows:
+
+
++-----------------+
+<project>
+  ...
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-war-plugin</artifactId>
+        <version>${project.version}</version>
+        <configuration>
+          <overlays>
+            <overlay>
+              <groupId>com.example.projects</groupId>
+              <artifactId>my-webapp</artifactId>
+            </overlay>
+            <overlay>
+              <!-- empty groupId/artifactId represents the current build -->
+            </overlay>
+          </overlays>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  ...
+</project>
++-----------------+
+
+  <<Note:>> In the scenario above, any other WAR dependency will be applied after the current build
+  since they have not been configured in the <<<\<overlays\>>>> element.
+
+  To perform an even more fine grained overwriting policy, overlays can be packaged multiple times
+  with different includes/excludes. For instance if the <<<index.jsp>>> file of the
+  overlay <<<my-webapp>>> <<must>> be set in the webapp but other files can be controlled the
+  regular way, define two overlay configurations for <<<my-webapp>>>:
+
++-----------------+
+<project>
+  ...
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-war-plugin</artifactId>
+        <version>${project.version}</version>
+        <configuration>
+          <overlays>
+            <overlay>
+              <id>my-webapp-index.jsp</id>
+              <groupId>com.example.projects</groupId>
+              <artifactId>my-webapp</artifactId>
+              <includes>
+                <include>index.jsp</include>
+              </includes>
+            </overlay>
+            <overlay>
+              <!-- empty groupId/artifactId represents the current build -->
+            </overlay>
+
+            <!-- Other overlays here if necessary -->
+
+            <overlay>
+              <id>my-webapp</id>
+              <groupId>com.example.projects</groupId>
+              <artifactId>my-webapp</artifactId>
+            </overlay>
+          </overlays>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  ...
+</project>
++-----------------+
+
+
+* Overlay global settings
+
+   The following settings can be specified globally and modify the way all overlays are applied.
+
+   * <<dependentWarIncludes>> - sets the default includes to apply to all overlays. Any overlay that
+    has no specific <<<includes>>> element will inherit this setting by default.
+
++-----------------+
+<project>
+    ...
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-war-plugin</artifactId>
+        <version>${project.version}</version>
+        <configuration>
+          <dependentWarIncludes>**/IncludeME,**/images</dependentWarIncludes>
+        </configuration>
+       </plugin>
+    </plugins>
+    ...
+</project>
++-----------------+
+
+   * <<dependentWarExcludes>> - sets the default excludes to apply to all overlays. Any overlay that
+    has no specific <<<excludes>>> element will inherit this setting by default.
+
++-----------------+
+<project>
+    ...
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-war-plugin</artifactId>
+        <version>${project.version}</version>
+        <configuration>
+          <dependentWarExcludes>WEB-INF/web.xml,index.*</dependentWarExcludes>
+        </configuration>
+       </plugin>
+    </plugins>
+    ...
+</project>
++-----------------+
+
+   * <<workDirectory>> - sets the directory where overlays will be temporarily extracted.
+
++-----------------+
+<project>
+    ...
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-war-plugin</artifactId>
+        <version>${project.version}</version>
+        <configuration>
+          <!-- default value is target/war/work -->
+          <workDirectory>/tmp/extract_here</workDirectory>
+        </configuration>
+       </plugin>
+    </plugins>
+    ...
+</project>
++-----------------+
+
+* Zip dependencies with overlays
+
+  To use a <<zip>> dependency as an overlay you have to configure it explicitly in the plugin's configuration. For
+  instance to inject the content of a zip overlay in the <<<scripts>>> directory of the webapp, do as follows:
+
++-----------------+
+<project>
+    ...
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-war-plugin</artifactId>
+        <version>${project.version}</version>
+        <configuration>
+          <overlays>
+            <overlay>
+              <groupId>zipGroupId</groupId>
+              <artifactId>zipArtifactId</artifactId>
+              <type>zip</type>
+              <targetPath>scripts</targetPath>
+            </overlay>
+          </overlays>
+        </configuration>
+      </plugin>
+    </plugins>
+    ...
+</project>
++-----------------+
diff --git a/Java-base/maven-war-plugin/src/src/site/apt/usage.apt.vm b/Java-base/maven-war-plugin/src/src/site/apt/usage.apt.vm
new file mode 100644
index 000000000..3e3b1cc0d
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/site/apt/usage.apt.vm
@@ -0,0 +1,229 @@
+ ------
+ Usage
+ ------
+ Pete Marvin King
+ ------
+ 2010-08-15
+ ------
+
+~~ 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.
+
+~~ NOTE: For help with the syntax of this file, see:
+~~ http://maven.apache.org/doxia/references/apt-format.html
+
+Usage
+
+ There are 4 ways to use the WAR Plugin:
+
+ * using the <<<package>>> phase with the project package type as <<<war>>>
+
+ * invocation of the <<<war:war>>> goal
+
+ * invocation of the <<<war:exploded>>> goal
+
+ * invocation of the <<<war:inplace>>> goal
+
+ []
+
+ <<Note:>> When using the <<<war:>>> goals it is assumed that the <<<compile>>> phase is already done.
+ The WAR Plugin is not responsible for compiling the java sources or copying the resources.
+
+ To handle archiving this version of Maven WAR Plugin uses
+ {{{http://maven.apache.org/shared/maven-archiver/index.html}Maven Archiver}} ${mavenArchiverVersion}.
+
+  To handle filtering this version of Maven WAR Plugin uses
+  {{{http://maven.apache.org/shared/maven-filtering/index.html}Maven Filtering}} ${mavenFilteringVersion}.
+
+
+*Using the <<<package>>> phase with the project package type as war / invocation of the <<<war:war>>> goal
+
+ This is the normal way of using the WAR Plugin.
+ To illustrate, here's the <<<pom.xml>>> for our project:
+
++----------+
+<project>
+  ...
+  <groupId>com.example.projects</groupId>
+  <artifactId>documentedproject</artifactId>
+  <packaging>war</packaging>
+  <version>1.0-SNAPSHOT</version>
+  <name>Documented Project</name>
+  <url>http://example.com</url>
+  ...
+</project>
++----------+
+
+ The project's structure looks like this:
+
+----------
+ |-- pom.xml
+ `-- src
+     `-- main
+         |-- java
+         |   `-- com
+         |       `-- example
+         |           `-- projects
+         |               `-- SampleAction.java
+         |-- resources
+         |   `-- images
+         |       `-- sampleimage.jpg
+         `-- webapp
+             |-- WEB-INF
+             |   `-- web.xml
+             |-- index.jsp
+             `-- jsp
+                 `-- websource.jsp
+----------
+
+ Invoking
+
+----------
+mvn package
+----------
+
+ or
+
+----------
+mvn compile war:war
+----------
+
+ will generate the WAR file <<<target/documentedproject-1.0-SNAPSHOT.war>>>. Here are the contents of that WAR file:
+
+----------
+documentedproject-1.0-SNAPSHOT.war
+  |-- META-INF
+  |   |-- MANIFEST.MF
+  |   `-- maven
+  |       `-- com.example.projects
+  |           `-- documentedproject
+  |               |-- pom.properties
+  |               `-- pom.xml
+  |-- WEB-INF
+  |   |-- classes
+  |   |   |-- com
+  |   |   |   `-- example
+  |   |   |       `-- projects
+  |   |   |           `-- SampleAction.class
+  |   |   `-- images
+  |   |       `-- sampleimage.jpg
+  |   `-- web.xml
+  |-- index.jsp
+  `-- jsp
+      `-- websource.jsp
+----------
+
+*Invocation of <<<war:exploded>>> goal
+
+ To speed up testing during the developement phase, <<<war:explode>>> can be used to generate the WAR in exploded
+ form.
+ Use the same project as above and invoke:
+
+----------
+mvn compile war:exploded
+----------
+
+ This will generate an exploded version of the WAR in <<<target/documentedproject-1.0-SNAPSHOT>>>.
+ The contents of that directory looks like this:
+
+----------
+ documentedproject-1.0-SNAPSHOT
+ |-- META-INF
+ |-- WEB-INF
+ |   |-- classes
+ |   |   |-- com
+ |   |   |   `-- example
+ |   |   |       `-- projects
+ |   |   |           `-- SampleAction.class
+ |   |   `-- images
+ |   |       `-- sampleimage.jpg
+ |   `-- web.xml
+ |-- index.jsp
+ `-- jsp
+     `-- websource.jsp
+----------
+
+ The default directory for the exploded WAR is <<<target/\<finalName\>>>>. The <<<finalName>>> is usually in the form
+ of <<<\<artifactId\>-\<version\>>>>.
+ This default directory can be overridden by specifying the <<<webappDirectory>>> parameter.
+
++-------+
+<project>
+  ...
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-war-plugin</artifactId>
+        <version>${project.version}</version>
+        <configuration>
+          <webappDirectory>/sample/servlet/container/deploy/directory</webappDirectory>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  ...
+</project>
++-------+
+
+*Invocation of <<<war:inplace>>> goal
+
+ Another variation of <<<war:exploded>>> is <<<war:inplace>>>. With <<<war:inplace>>> the exploded WAR is created
+ in the webapp source, which defaults to <<<src/main/webapp>>>.
+ Use our sample project above, and invoke:
+
+----------
+mvn compile war:inplace
+----------
+
+ This will result in:
+
+----------
+ |-- pom.xml
+ |-- src
+ |   `-- main
+ |       |-- java
+ |       |   `-- com
+ |       |       `-- example
+ |       |           `-- projects
+ |       |               `-- SampleAction.java
+ |       |-- resources
+ |       |   `-- images
+ |       |       `-- sampleimage.jpg
+ |       `-- webapp
+ |           |-- META-INF
+ |           |-- WEB-INF
+ |           |   |-- classes
+ |           |   |   |-- com
+ |           |   |   |   `-- example
+ |           |   |   |       `-- projects
+ |           |   |   |           `-- SampleAction.class
+ |           |   |   `-- images
+ |           |   |       `-- sampleimage.jpg
+ |           |   `-- web.xml
+ |           |-- index.jsp
+ |           `-- jsp
+ |               `-- websource.jsp
+ `-- target
+     `-- classes
+         |-- com
+         |   `-- example
+         |       `-- projects
+         |           `-- SampleAction.class
+         `-- images
+             `-- sampleimage.jpg
+----------
diff --git a/Java-base/maven-war-plugin/src/src/site/fml/faq.fml.vm b/Java-base/maven-war-plugin/src/src/site/fml/faq.fml.vm
new file mode 100644
index 000000000..19fc6f81c
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/site/fml/faq.fml.vm
@@ -0,0 +1,141 @@
+<?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.
+-->
+
+
+<faqs xmlns="http://maven.apache.org/FML/1.0.1"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/FML/1.0.1 http://maven.apache.org/xsd/fml-1.0.1.xsd"
+  id="FAQ" title="Frequently Asked Questions">
+ <part id="General">
+   <faq id="filtering">
+     <question>How is filtering done in the WAR plugin?</question>
+     <answer>
+       <p>To enable filtering of <code>web.xml</code> you must configure the WAR Plugin like this:
+         <source><![CDATA[
+      <plugin>
+        <artifactId>maven-war-plugin</artifactId>
+        <version>${project.version}</version>
+        <configuration>
+          <filteringDeploymentDescriptors>true</filteringDeploymentDescriptors>
+        </configuration>
+      </plugin>
+]]></source>
+       </p>
+       <p>Examples can be found <a href="examples/adding-filtering-webresources.html">here</a>.</p>
+     </answer>
+   </faq>
+   <faq id="classifieruse">
+     <question>How does the classifier of dependency artifacts affect my WAR project?</question>
+     <answer>
+       <p>When used, the copy of the dependency artifact in your project will have the classifier appended to its
+       filename. This can be used to differentiate duplicate artifacts.</p>
+     </answer>
+   </faq>
+   <faq id="transitiveexclude">
+     <question>How do I exclude transitive dependencies from my project?</question>
+     <answer>
+       <p>Give it a "provided" scope.</p>
+     </answer>
+   </faq>
+   <faq id="dependentwarexclude">
+     <question>What's the difference between using dependentWarExclude and provided scope?</question>
+     <answer>
+       <p><code>dependentWarExclude</code> is used in <a href="overlays.html">overlays</a> for excluding dependent
+       WAR files from the assembled webapp.</p>
+     </answer>
+   </faq>
+   <faq id="webresourcesexclude">
+     <question>How do I exclude files in my web resources?</question>
+     <answer>
+       <p>Use the <code>&lt;webResources&gt;</code> / <code>&lt;exclude&gt;</code> parameter to identify the tokens to exclude.</p>
+       <p>For more information refer to <a href="examples/adding-filtering-webresources.html">Adding and Filtering
+       External Web Resources</a>.</p>
+     </answer>
+   </faq>
+   <faq id="waroverlaysexclude">
+     <question>How do I exclude files when doing overlays?</question>
+     <answer>
+       <p>Use the <code>dependentWarExcludes</code> parameter to identify the tokens to exclude.</p>
+     </answer>
+   </faq>
+   <faq id="configurationdoc">
+     <question>Where can I find the documentation for the plugin's configuration?</question>
+     <answer>
+       <p>
+         For each goal, you can use the documentation from the <a href="plugin-info.html">plugin site</a>.
+       </p>
+       <p>
+         If you need a specific version, generate it using <code>mvn site:site</code> or use:
+         <source><![CDATA[
+mvn help:describe -Dplugin=war -Dfull=true -Dversion=<your-plugin-version-here>
+]]></source>
+       </p>
+     </answer>
+   </faq>
+   <faq id="attached">
+     <question>How do I create a JAR containing the classes in my webapp?</question>
+       <answer>
+       <p>If you would simply like to package the classes and resources as a JAR in <code>WEB-INF/lib</code>
+           rather than as loose files under <code>WEB-INF/classes</code>, use the following configuration:</p>
+       <p>
+         <source><![CDATA[
+      <plugin>
+        <artifactId>maven-war-plugin</artifactId>
+        <version>${project.version}</version>
+        <configuration>
+          <archiveClasses>true</archiveClasses>
+        </configuration>
+      </plugin>
+]]></source>
+       </p>
+       <p>If you need to re-use this JAR in another project, the recommended approach is to move the classes to a
+       separate module that builds a JAR, and then declare a dependency on that JAR from your webapp as well as from
+       any other projects that need it.</p>
+       <p>If you can't move the classes to another project, you can deploy the classes and resources included in
+           your webapp as an "attached" artifact, with a classifier, by using the following configuration:</p>
+       <p>
+         <source><![CDATA[
+<project>
+  ...
+  <artifactId>mywebapp</artifactId>
+  <version>1.0-SNAPSHOT</version>
+  ...
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-war-plugin</artifactId>
+        <version>${project.version}</version>
+        <configuration>
+          <attachClasses>true</attachClasses>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  ...
+</project>
+]]></source>
+       </p>
+       <p>This will result in two artifacts being deployed: <code>mywebapp-1.0-SNAPSHOT.war</code>
+       and <code>mywebapp-1.0-SNAPSHOT-classes.jar</code>.</p>
+     </answer>
+   </faq>
+ </part>
+</faqs>
\ No newline at end of file
diff --git a/Java-base/maven-war-plugin/src/src/site/resources/download.cgi b/Java-base/maven-war-plugin/src/src/site/resources/download.cgi
new file mode 100644
index 000000000..1b178d2e6
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/site/resources/download.cgi
@@ -0,0 +1,22 @@
+#!/bin/sh
+#
+# 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.
+#
+# Just call the standard mirrors.cgi script. It will use download.html
+# as the input template.
+exec /www/www.apache.org/dyn/mirrors/mirrors.cgi $*
\ No newline at end of file
diff --git a/Java-base/maven-war-plugin/src/src/site/site.xml b/Java-base/maven-war-plugin/src/src/site/site.xml
new file mode 100644
index 000000000..2f81f26ca
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/site/site.xml
@@ -0,0 +1,48 @@
+<?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.
+-->
+
+<project xmlns="http://maven.apache.org/DECORATION/1.0.0"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/DECORATION/1.0.0 http://maven.apache.org/xsd/decoration-1.0.0.xsd">
+
+  <body>
+    <menu name="Overview">
+      <item name="Introduction" href="index.html"/>
+      <item name="Goals" href="plugin-info.html"/>
+      <item name="Usage" href="usage.html"/>
+      <item name="FAQ" href="faq.html"/>
+      <!-- According to https://issues.apache.org/jira/browse/MNGSITE-152 -->
+      <item name="License" href="http://www.apache.org/licenses/"/>
+      <item name="Download" href="download.html"/>
+    </menu>
+    <menu name="Configuration">
+      <item name="Overlays" href="overlays.html"/>
+    </menu>
+    <menu name="Examples">
+      <item name="Adding and Filtering External Web Resources" href="examples/adding-filtering-webresources.html"/>
+      <item name="WAR Manifest Customization" href="examples/war-manifest-guide.html"/>
+      <item name="Rapid Testing Using the Jetty Plugin" href="examples/rapid-testing-jetty6-plugin.html"/>
+      <item name="Creating Skinny WARs" href="examples/skinny-wars.html"/>
+      <item name="Including and Excluding Files From the WAR" href="examples/including-excluding-files-from-war.html"/>
+      <item name="Using File Name Mapping" href="examples/file-name-mapping.html"/>
+    </menu>
+  </body>
+</project>
diff --git a/Java-base/maven-war-plugin/src/src/site/xdoc/download.xml.vm b/Java-base/maven-war-plugin/src/src/site/xdoc/download.xml.vm
new file mode 100644
index 000000000..3f710359a
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/site/xdoc/download.xml.vm
@@ -0,0 +1,126 @@
+<?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>Download ${project.name} Source</title>
+  </properties>
+  <body>
+    <section name="Download ${project.name} ${project.version} Source">
+
+      <p>${project.name} ${project.version} is distributed in source format. Use a source archive if you intend to build
+      ${project.name} yourself. Otherwise, simply use the ready-made binary artifacts from central repository.</p>
+
+      <p>You will be prompted for a mirror - if the file is not found on yours, please be patient, as it may take 24
+      hours to reach all mirrors.<p/>
+
+      <p>In order to guard against corrupted downloads/installations, it is highly recommended to
+      <a href="http://www.apache.org/dev/release-signing#verifying-signature">verify the signature</a>
+      of the release bundles against the public <a href="https://www.apache.org/dist/maven/KEYS">KEYS</a> used by the Apache Maven
+      developers.</p>
+
+      <p>${project.name} is distributed under the <a href="http://www.apache.org/licenses/">Apache License, version 2.0</a>.</p>
+
+      <p></p>We <b>strongly</b> encourage our users to configure a Maven repository mirror closer to their location, please read <a href="/guides/mini/guide-mirror-settings.html">How to Use Mirrors for Repositories</a>.</p>
+
+      <a name="mirror"/>
+      <subsection name="Mirror">
+
+        <p>
+          [if-any logo]
+          <a href="[link]">
+            <img align="right" src="[logo]" border="0"
+                 alt="logo"/>
+          </a>
+          [end]
+          The currently selected mirror is
+          <b>[preferred]</b>.
+          If you encounter a problem with this mirror,
+          please select another mirror.
+          If all mirrors are failing, there are
+          <i>backup</i>
+          mirrors
+          (at the end of the mirrors list) that should be available.
+        </p>
+
+        <form action="[location]" method="get" id="SelectMirror">
+          Other mirrors:
+          <select name="Preferred">
+            [if-any http]
+            [for http]
+            <option value="[http]">[http]</option>
+            [end]
+            [end]
+            [if-any ftp]
+            [for ftp]
+            <option value="[ftp]">[ftp]</option>
+            [end]
+            [end]
+            [if-any backup]
+            [for backup]
+            <option value="[backup]">[backup] (backup)</option>
+            [end]
+            [end]
+          </select>
+          <input type="submit" value="Change"/>
+        </form>
+
+        <p>
+          You may also consult the
+          <a href="http://www.apache.org/mirrors/">complete list of
+            mirrors.</a>
+        </p>
+
+      </subsection>
+      
+      <subsection name="${project.name} ${project.version}">
+        
+      <p>This is the current stable version of ${project.name}.</p>
+        
+      <table>
+        <thead>
+          <tr>
+            <th></th>
+            <th>Link</th>
+            <th>Checksum</th>
+            <th>Signature</th>
+          </tr>
+        </thead>
+        <tbody>
+          <tr>
+            <td>${project.name} ${project.version} (Source zip)</td>
+            <td><a href="[preferred]maven/plugins/${project.artifactId}-${project.version}-source-release.zip">maven/plugins/${project.artifactId}-${project.version}-source-release.zip</a></td>
+            <td><a href="https://www.apache.org/dist/maven/plugins/${project.artifactId}-${project.version}-source-release.zip.sha512">maven/plugins/${project.artifactId}-${project.version}-source-release.zip.sha512</a></td>
+            <td><a href="https://www.apache.org/dist/maven/plugins/${project.artifactId}-${project.version}-source-release.zip.asc">maven/plugins/${project.artifactId}-${project.version}-source-release.zip.asc</a></td>
+          </tr>
+        </tbody>
+      </table>
+      </subsection>
+
+      <subsection name="Previous Versions">
+        
+      <p>Older non-recommended releases can be found on our <a href="http://archive.apache.org/dist/maven/plugins/">archive site</a>.</p>
+
+      </subsection>
+    </section>
+  </body>
+</document>
+
diff --git a/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/AbstractWarExplodedMojoTest.java b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/AbstractWarExplodedMojoTest.java
new file mode 100644
index 000000000..d7c897aa0
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/AbstractWarExplodedMojoTest.java
@@ -0,0 +1,303 @@
+package org.apache.maven.plugins.war;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.plugin.testing.stubs.ArtifactStub;
+import org.apache.maven.plugins.war.stub.MavenProjectArtifactsStub;
+import org.codehaus.plexus.util.FileUtils;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * @author Stephane Nicoll
+ */
+public abstract class AbstractWarExplodedMojoTest
+    extends AbstractWarMojoTest
+{
+
+    protected WarExplodedMojo mojo;
+
+    public void setUp()
+        throws Exception
+    {
+        super.setUp();
+        mojo = (WarExplodedMojo) lookupMojo( "exploded", getPomFile() );
+    }
+
+    /**
+     * Returns the pom configuration to use.
+     *
+     * @return the pom configuration
+     */
+    protected abstract File getPomFile();
+
+    /**
+     * Returns the test directory to use.
+     *
+     * @return the test directory
+     */
+    protected abstract File getTestDirectory();
+
+    /**
+     * Configures the exploded mojo for the specified test.
+     * 
+     * If the <tt>sourceFiles</tt> parameter is <tt>null</tt>, sample JSPs are created by default.
+     *
+     * @param testId the id of the test
+     * @param artifactStubs the dependencies (may be null)
+     * @param sourceFiles the source files to create (may be null)
+     * @return the webapp directory
+     * @throws Exception if an error occurs while configuring the mojo
+     */
+    protected File setUpMojo( final String testId, ArtifactStub[] artifactStubs, String[] sourceFiles )
+        throws Exception
+    {
+        final MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
+        final File webAppDirectory = new File( getTestDirectory(), testId );
+
+        // Create the webapp sources
+        File webAppSource;
+        if ( sourceFiles == null )
+        {
+            webAppSource = createWebAppSource( testId );
+        }
+        else
+        {
+            webAppSource = createWebAppSource( testId, false );
+            for ( String sourceFile : sourceFiles )
+            {
+                File sample = new File( webAppSource, sourceFile );
+                createFile( sample );
+
+            }
+
+        }
+
+        final File classesDir = createClassesDir( testId, true );
+        final File workDirectory = new File( getTestDirectory(), "/war/work-" + testId );
+        createDir( workDirectory );
+
+        if ( artifactStubs != null )
+        {
+            for ( ArtifactStub artifactStub : artifactStubs )
+            {
+                project.addArtifact( artifactStub );
+            }
+        }
+
+        configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
+        setVariableValueToObject( mojo, "workDirectory", workDirectory );
+
+        return webAppDirectory;
+    }
+
+    /**
+     * Configures the exploded mojo for the specified test.
+     *
+     * @param testId the id of the test
+     * @param artifactStubs the dependencies (may be null)
+     * @return the webapp directory
+     * @throws Exception if an error occurs while configuring the mojo
+     */
+    protected File setUpMojo( final String testId, ArtifactStub[] artifactStubs )
+        throws Exception
+    {
+        return setUpMojo( testId, artifactStubs, null );
+    }
+
+    /**
+     * Cleans up a directory.
+     *
+     * @param directory the directory to remove
+     * @throws IOException if an error occurred while removing the directory
+     */
+    protected void cleanDirectory( File directory )
+        throws IOException
+    {
+        if ( directory != null && directory.isDirectory() && directory.exists() )
+        {
+            FileUtils.deleteDirectory( directory );
+        }
+    }
+
+    /**
+     * Asserts the default content of the war based on the specified webapp directory.
+     *
+     * @param webAppDirectory the webapp directory
+     * @return a list of File objects that have been asserted
+     */
+    protected List<File> assertDefaultContent( File webAppDirectory )
+    {
+        // Validate content of the webapp
+        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
+        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
+
+        assertTrue( "source file not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
+        assertTrue( "source file not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
+
+        final List<File> content = new ArrayList<>();
+        content.add( expectedWebSourceFile );
+        content.add( expectedWebSource2File );
+
+        return content;
+    }
+
+    /**
+     * Asserts the web.xml file of the war based on the specified webapp directory.
+     *
+     * @param webAppDirectory the webapp directory
+     * @return a list with the web.xml File object
+     */
+    protected List<File> assertWebXml( File webAppDirectory )
+    {
+        File expectedWEBXMLFile = new File( webAppDirectory, "WEB-INF/web.xml" );
+        assertTrue( "web xml not found: " + expectedWEBXMLFile.toString(), expectedWEBXMLFile.exists() );
+
+        final List<File> content = new ArrayList<>();
+        content.add( expectedWEBXMLFile );
+
+        return content;
+    }
+
+    /**
+     * Asserts custom content of the war based on the specified webapp directory.
+     *
+     * @param webAppDirectory the webapp directory
+     * @param filePaths an array of file paths relative to the webapp directory
+     * @param customMessage a custom message if an assertion fails
+     * @return a list of File objects that have been inspected
+     */
+    protected List<File> assertCustomContent( File webAppDirectory, String[] filePaths, String customMessage )
+    {
+        final List<File> content = new ArrayList<>();
+        for ( String filePath : filePaths )
+        {
+            final File expectedFile = new File( webAppDirectory, filePath );
+            if ( customMessage != null )
+            {
+                assertTrue( customMessage + " - " + expectedFile.toString(), expectedFile.exists() );
+            }
+            else
+            {
+                assertTrue( "source file not found: " + expectedFile.toString(), expectedFile.exists() );
+            }
+            content.add( expectedFile );
+        }
+        return content;
+    }
+
+    /**
+     * Asserts that the webapp contains only the specified files.
+     *
+     * @param webAppDirectory the webapp directory
+     * @param expectedFiles the expected files
+     * @param filter an optional filter to ignore some resources
+     */
+    protected void assertWebAppContent( File webAppDirectory, List<File> expectedFiles, FileFilter filter )
+    {
+        final List<File> webAppContent = new ArrayList<>();
+        if ( filter != null )
+        {
+            buildFilesList( webAppDirectory, filter, webAppContent );
+        }
+        else
+        {
+            buildFilesList( webAppDirectory, new FileFilterImpl( webAppDirectory, null ), webAppContent );
+        }
+
+        // Now we have the files, sort them.
+        Collections.sort( expectedFiles );
+        Collections.sort( webAppContent );
+        assertEquals( "Invalid webapp content, expected " + expectedFiles.size() + "file(s) " + expectedFiles
+            + " but got " + webAppContent.size() + " file(s) " + webAppContent, expectedFiles, webAppContent );
+    }
+
+    /**
+     * Builds the list of files and directories from the specified dir.
+     * 
+     * Note that the filter is not used the usual way. If the filter does not accept the current file, it's not added
+     * but yet the subdirectories are added if any.
+     *
+     * @param dir the base directory
+     * @param filter the filter
+     * @param content the current content, updated recursively
+     */
+    private void buildFilesList( final File dir, FileFilter filter, final List<File> content )
+    {
+        final File[] files = dir.listFiles();
+
+        for ( File file : files )
+        {
+            // Add the file if the filter is ok with it
+            if ( filter.accept( file ) )
+            {
+                content.add( file );
+            }
+
+            // Even if the file is not accepted and is a directory, add it
+            if ( file.isDirectory() )
+            {
+                buildFilesList( file, filter, content );
+            }
+
+        }
+    }
+
+    class FileFilterImpl
+        implements FileFilter
+    {
+
+        private final List<String> rejectedFilePaths;
+
+        private final int webAppDirIndex;
+
+        public FileFilterImpl( File webAppDirectory, String[] rejectedFilePaths )
+        {
+            if ( rejectedFilePaths != null )
+            {
+                this.rejectedFilePaths = Arrays.asList( rejectedFilePaths );
+            }
+            else
+            {
+                this.rejectedFilePaths = new ArrayList<>();
+            }
+            this.webAppDirIndex = webAppDirectory.getAbsolutePath().length() + 1;
+        }
+
+        public boolean accept( File file )
+        {
+            String effectiveRelativePath = buildRelativePath( file );
+            return !( rejectedFilePaths.contains( effectiveRelativePath ) || file.isDirectory() );
+        }
+
+        private String buildRelativePath( File f )
+        {
+            return f.getAbsolutePath().substring( webAppDirIndex );
+        }
+    }
+
+}
diff --git a/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/AbstractWarMojoTest.java b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/AbstractWarMojoTest.java
new file mode 100644
index 000000000..87344ad26
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/AbstractWarMojoTest.java
@@ -0,0 +1,332 @@
+package org.apache.maven.plugins.war;
+
+/*
+ * 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.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.maven.execution.DefaultMavenExecutionRequest;
+import org.apache.maven.execution.MavenExecutionRequest;
+import org.apache.maven.execution.MavenSession;
+import org.apache.maven.plugin.testing.AbstractMojoTestCase;
+import org.apache.maven.plugin.testing.stubs.ArtifactStub;
+import org.apache.maven.plugins.war.AbstractWarMojo;
+import org.apache.maven.plugins.war.stub.MavenProjectBasicStub;
+import org.apache.maven.plugins.war.stub.WarOverlayStub;
+import org.apache.maven.shared.filtering.MavenFileFilter;
+import org.codehaus.plexus.PlexusContainer;
+import org.codehaus.plexus.archiver.Archiver;
+import org.codehaus.plexus.archiver.ArchiverException;
+import org.codehaus.plexus.archiver.jar.JarArchiver;
+import org.codehaus.plexus.util.FileUtils;
+import org.sonatype.aether.RepositorySystemSession;
+
+public abstract class AbstractWarMojoTest
+    extends AbstractMojoTestCase
+{
+
+    protected static final File OVERLAYS_TEMP_DIR = new File( getBasedir(), "target/test-overlays/" );
+
+    protected static final File OVERLAYS_ROOT_DIR = new File( getBasedir(), "target/test-classes/overlays/" );
+
+    protected static final String MANIFEST_PATH = "META-INF" + File.separator + "MANIFEST.MF";
+
+    protected abstract File getTestDirectory()
+        throws Exception;
+
+    /**
+     * initialize required parameters
+     *
+     * @param mojo The mojo to be tested.
+     * @param filters The list of filters.
+     * @param classesDir The classes directory.
+     * @param webAppSource The webAppSource.
+     * @param webAppDir The webAppDir folder.
+     * @param project The Maven project.
+     * @throws Exception in case of errors
+     */
+    protected void configureMojo( AbstractWarMojo mojo, List<String> filters, File classesDir, File webAppSource,
+                                  File webAppDir, MavenProjectBasicStub project )
+                                      throws Exception
+    {
+        setVariableValueToObject( mojo, "filters", filters );
+        setVariableValueToObject( mojo, "mavenFileFilter", lookup( MavenFileFilter.class.getName() ) );
+        setVariableValueToObject( mojo, "useJvmChmod", Boolean.TRUE );
+
+        MavenExecutionRequest request = new DefaultMavenExecutionRequest();
+        request.setSystemProperties( System.getProperties() );
+
+        MavenSession mavenSession =
+            new MavenSession( (PlexusContainer) null, (RepositorySystemSession) null, request, null );
+        setVariableValueToObject( mojo, "session", mavenSession );
+        mojo.setClassesDirectory( classesDir );
+        mojo.setWarSourceDirectory( webAppSource );
+        mojo.setWebappDirectory( webAppDir );
+        mojo.setProject( project );
+    }
+
+    /**
+     * create an isolated xml dir
+     *
+     * @param id The id.
+     * @param xmlFiles array of xml files.
+     * @return The created file.
+     * @throws Exception in case of errors.
+     */
+    protected File createXMLConfigDir( String id, String[] xmlFiles )
+        throws Exception
+    {
+        File xmlConfigDir = new File( getTestDirectory(), "/" + id + "-test-data/xml-config" );
+        File XMLFile;
+
+        createDir( xmlConfigDir );
+
+        if ( xmlFiles != null )
+        {
+            for ( String o : xmlFiles )
+            {
+                XMLFile = new File( xmlConfigDir, o );
+                createFile( XMLFile );
+            }
+        }
+
+        return xmlConfigDir;
+    }
+
+    /**
+     * Returns the webapp source directory for the specified id.
+     *
+     * @param id the id of the test
+     * @return the source directory for that test
+     * @throws Exception if an exception occurs
+     */
+    protected File getWebAppSource( String id )
+        throws Exception
+    {
+        return new File( getTestDirectory(), "/" + id + "-test-data/source" );
+    }
+
+    /**
+     * create an isolated web source with a sample jsp file
+     *
+     * @param id The id.
+     * @param createSamples Create example files yes or no.
+     * @return The created file.
+     * @throws Exception in case of errors.
+     */
+    protected File createWebAppSource( String id, boolean createSamples )
+        throws Exception
+    {
+        File webAppSource = getWebAppSource( id );
+        if ( createSamples )
+        {
+            File simpleJSP = new File( webAppSource, "pansit.jsp" );
+            File jspFile = new File( webAppSource, "org/web/app/last-exile.jsp" );
+
+            createFile( simpleJSP );
+            createFile( jspFile );
+        }
+        return webAppSource;
+    }
+
+    protected File createWebAppSource( String id )
+        throws Exception
+    {
+        return createWebAppSource( id, true );
+    }
+
+    /**
+     * create a class directory with or without a sample class
+     *
+     * @param id The id.
+     * @param empty true to create a class files false otherwise.
+     * @return The created class file.
+     * @throws Exception in case of errors.
+     */
+    protected File createClassesDir( String id, boolean empty )
+        throws Exception
+    {
+        File classesDir = new File( getTestDirectory() + "/" + id + "-test-data/classes/" );
+
+        createDir( classesDir );
+
+        if ( !empty )
+        {
+            createFile( new File( classesDir + "/sample-servlet.class" ) );
+        }
+
+        return classesDir;
+    }
+
+    protected void createDir( File dir )
+    {
+        if ( !dir.exists() )
+        {
+            assertTrue( "can not create test dir: " + dir.toString(), dir.mkdirs() );
+        }
+    }
+
+    protected void createFile( File testFile, String body )
+        throws Exception
+    {
+        createDir( testFile.getParentFile() );
+        FileUtils.fileWrite( testFile.toString(), body );
+
+        assertTrue( "could not create file: " + testFile, testFile.exists() );
+    }
+
+    protected void createFile( File testFile )
+        throws Exception
+    {
+        createFile( testFile, testFile.toString() );
+    }
+
+    /**
+     * Generates test war.
+     * Generates war with such a structure:
+     * <ul>
+     * <li>jsp
+     * <ul>
+     * <li>d
+     * <ul>
+     * <li>a.jsp</li>
+     * <li>b.jsp</li>
+     * <li>c.jsp</li>
+     * </ul>
+     * </li>
+     * <li>a.jsp</li>
+     * <li>b.jsp</li>
+     * <li>c.jsp</li>
+     * </ul>
+     * </li>
+     * <li>WEB-INF
+     * <ul>
+     * <li>classes
+     * <ul>
+     * <li>a.class</li>
+     * <li>b.class</li>
+     * <li>c.class</li>
+     * </ul>
+     * </li>
+     * <li>lib
+     * <ul>
+     * <li>a.jar</li>
+     * <li>b.jar</li>
+     * <li>c.jar</li>
+     * </ul>
+     * </li>
+     * <li>web.xml</li>
+     * </ul>
+     * </li>
+     * </ul>
+     * Each of the files will contain: id+'-'+path
+     *
+     * @param id the id of the overlay containing the full structure
+     * @return the war file
+     * @throws Exception if an error occurs
+     */
+    protected File generateFullOverlayWar( String id )
+        throws Exception
+    {
+        final File destFile = new File( OVERLAYS_TEMP_DIR, id + ".war" );
+        if ( destFile.exists() )
+        {
+            return destFile;
+        }
+
+        // Archive was not yet created for that id so let's create it
+        final File rootDir = new File( OVERLAYS_ROOT_DIR, id );
+        rootDir.mkdirs();
+        String[] filePaths = new String[] { "jsp/d/a.jsp", "jsp/d/b.jsp", "jsp/d/c.jsp", "jsp/a.jsp", "jsp/b.jsp",
+            "jsp/c.jsp", "WEB-INF/classes/a.class", "WEB-INF/classes/b.class", "WEB-INF/classes/c.class",
+            "WEB-INF/lib/a.jar", "WEB-INF/lib/b.jar", "WEB-INF/lib/c.jar", "WEB-INF/web.xml" };
+
+        for ( String filePath : filePaths )
+        {
+            createFile( new File( rootDir, filePath ), id + "-" + filePath );
+        }
+
+        createArchive( rootDir, destFile );
+        return destFile;
+    }
+
+    // Overlay utilities
+
+    /**
+     * Builds a test overlay.
+     *
+     * @param id the id of the overlay (see test/resources/overlays)
+     * @return a test war artifact with the content of the given test overlay
+     */
+    protected ArtifactStub buildWarOverlayStub( String id )
+    {
+        // Create war file
+        final File destFile = new File( OVERLAYS_TEMP_DIR, id + ".war" );
+        if ( !destFile.exists() )
+        {
+            createArchive( new File( OVERLAYS_ROOT_DIR, id ), destFile );
+        }
+
+        return new WarOverlayStub( getBasedir(), id, destFile );
+    }
+
+    protected File getOverlayFile( String id, String filePath )
+    {
+        final File overlayDir = new File( OVERLAYS_ROOT_DIR, id );
+        final File file = new File( overlayDir, filePath );
+
+        // Make sure the file exists
+        assertTrue( "Overlay file " + filePath + " does not exist for overlay " + id + " at " + file.getAbsolutePath(),
+                    file.exists() );
+        return file;
+
+    }
+
+    protected void createArchive( final File directory, final File destinationFile )
+    {
+        try
+        {
+            // WarArchiver archiver = new WarArchiver();
+
+            Archiver archiver = new JarArchiver();
+
+            archiver.setDestFile( destinationFile );
+            archiver.addDirectory( directory );
+
+            // archiver.setWebxml( new File(directory, "WEB-INF/web.xml"));
+
+            // create archive
+            archiver.createArchive();
+
+        }
+        catch ( ArchiverException e )
+        {
+            e.printStackTrace();
+            fail( "Failed to create overlay archive " + e.getMessage() );
+        }
+        catch ( IOException e )
+        {
+            e.printStackTrace();
+            fail( "Unexpected exception " + e.getMessage() );
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/WarExplodedMojoFilteringTest.java b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/WarExplodedMojoFilteringTest.java
new file mode 100644
index 000000000..9997f4d68
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/WarExplodedMojoFilteringTest.java
@@ -0,0 +1,209 @@
+package org.apache.maven.plugins.war;
+
+/*
+ * 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.
+ */
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.StringReader;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.maven.plugins.war.stub.MavenProjectBasicStub;
+import org.apache.maven.plugins.war.stub.ResourceStub;
+import org.codehaus.plexus.util.FileUtils;
+
+/**
+ * @author Olivier Lamy
+ * @since 21 juil. 2008
+ */
+public class WarExplodedMojoFilteringTest
+    extends AbstractWarExplodedMojoTest
+{
+
+    protected File getPomFile()
+    {
+        return new File( getBasedir(), "/target/test-classes/unit/warexplodedmojo/plugin-config.xml" );
+    }
+
+    protected File getTestDirectory()
+    {
+        return new File( getBasedir(), "target/test-classes/unit/warexplodedmojo/test-dir" );
+    }
+
+    /**
+     * @throws Exception in case of an error.
+     */
+    public void testExplodedWar_WithResourceFiltering()
+        throws Exception
+    {
+        // setup test data
+        String testId = "ExplodedWar_WithResourceFiltering";
+        MavenProjectBasicStub project = new MavenProjectBasicStub();
+        File webAppDirectory = new File( getTestDirectory(), testId );
+        File webAppSource = createWebAppSource( testId );
+        File classesDir = createClassesDir( testId, false );
+        File webAppResource = new File( getTestDirectory(), testId + "-test-data/resources" );
+        File sampleResource = new File( webAppResource, "custom-setting.cfg" );
+        File sampleResourceWDir = new File( webAppResource, "custom-config/custom-setting.cfg" );
+        List<String> filterList = new LinkedList<>();
+        ResourceStub[] resources = new ResourceStub[] { new ResourceStub() };
+
+        createFile( sampleResource );
+        createFile( sampleResourceWDir );
+
+        String ls = System.getProperty( "line.separator" );
+        final String comment = "# this is comment created by author@somewhere@";
+        // prepare web resources
+        String content = comment + ls;
+        content += "system_key_1=${user.dir}" + ls;
+        content += "system_key_2=@user.dir@" + ls;
+        content += "project_key_1=${is_this_simple}" + ls;
+        content += "project_key_2=@is_this_simple@" + ls;
+        content += "project_name_1=${project.name}" + ls;
+        content += "project_name_2=@project.name@" + ls;
+        content += "system_property_1=${system.property}" + ls;
+        content += "system_property_2=@system.property@" + ls;
+        FileUtils.fileWrite( sampleResourceWDir.getAbsolutePath(), content );
+        FileUtils.fileWrite( sampleResource.getAbsolutePath(), content );
+
+        System.setProperty( "system.property", "system-property-value" );
+
+        // configure mojo
+        project.addProperty( "is_this_simple", "i_think_so" );
+        resources[0].setDirectory( webAppResource.getAbsolutePath() );
+        resources[0].setFiltering( true );
+        this.configureMojo( mojo, filterList, classesDir, webAppSource, webAppDirectory, project );
+        setVariableValueToObject( mojo, "webResources", resources );
+        mojo.execute();
+
+        // validate operation
+        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
+        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
+        File expectedResourceFile = new File( webAppDirectory, "custom-setting.cfg" );
+        File expectedResourceWDirFile = new File( webAppDirectory, "custom-config/custom-setting.cfg" );
+
+        assertTrue( "source files not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
+        assertTrue( "source files not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
+        assertTrue( "resource file not found:" + expectedResourceFile.toString(), expectedResourceFile.exists() );
+        assertTrue( "resource file with dir not found:" + expectedResourceWDirFile.toString(),
+                    expectedResourceWDirFile.exists() );
+
+        // validate filtered file
+        content = FileUtils.fileRead( expectedResourceWDirFile );
+        BufferedReader reader = new BufferedReader( new StringReader( content ) );
+
+        assertEquals( "error in filtering using System Properties", comment, reader.readLine() );
+
+        String line = reader.readLine();
+        System.out.println( " line " + line );
+        System.out.println( " need " + System.getProperty( "user.dir" ) );
+        assertEquals( "error in filtering using System properties", "system_key_1=" + System.getProperty( "user.dir" ),
+                      line );
+        line = reader.readLine();
+        System.out.println( " line " + line );
+        assertEquals( "error in filtering using System properties", "system_key_2=" + System.getProperty( "user.dir" ),
+                      line );
+
+        assertEquals( "error in filtering using project properties", "project_key_1=i_think_so", reader.readLine() );
+        assertEquals( "error in filtering using project properties", "project_key_2=i_think_so", reader.readLine() );
+
+        assertEquals( "error in filtering using project properties", "project_name_1=Test Project ", reader.readLine() );
+        assertEquals( "error in filtering using project properties", "project_name_2=Test Project ", reader.readLine() );
+
+        assertEquals( "error in filtering using System properties", "system_property_1=system-property-value",
+                      reader.readLine() );
+        assertEquals( "error in filtering using System properties", "system_property_2=system-property-value",
+                      reader.readLine() );
+
+        // update property, and generate again
+        System.setProperty( "system.property", "new-system-property-value" );
+        this.configureMojo( mojo, filterList, classesDir, webAppSource, webAppDirectory, project );
+
+        mojo.execute();
+
+        // validate filtered file
+        content = FileUtils.fileRead( expectedResourceWDirFile );
+        reader = new BufferedReader( new StringReader( content ) );
+
+        assertEquals( "error in filtering using System Properties", comment, reader.readLine() );
+
+        assertEquals( "error in filtering using System properties", "system_key_1=" + System.getProperty( "user.dir" ),
+                      reader.readLine() );
+        assertEquals( "error in filtering using System properties", "system_key_2=" + System.getProperty( "user.dir" ),
+                      reader.readLine() );
+
+        assertEquals( "error in filtering using project properties", "project_key_1=i_think_so", reader.readLine() );
+        assertEquals( "error in filtering using project properties", "project_key_2=i_think_so", reader.readLine() );
+
+        assertEquals( "error in filtering using project properties", "project_name_1=Test Project ", reader.readLine() );
+        assertEquals( "error in filtering using project properties", "project_name_2=Test Project ", reader.readLine() );
+
+        assertEquals( "error in filtering using System properties", "system_property_1=new-system-property-value",
+                      reader.readLine() );
+        assertEquals( "error in filtering using System properties", "system_property_2=new-system-property-value",
+                      reader.readLine() );
+
+        // update property, and generate again
+        File filterFile = new File( getTestDirectory(), testId + "-test-data/filters/filter.properties" );
+        createFile( filterFile );
+        filterList.add( filterFile.getAbsolutePath() );
+        content += "resource_key_1=${resource_value_1}\n";
+        content += "resource_key_2=@resource_value_2@\n" + content;
+        FileUtils.fileWrite( sampleResourceWDir.getAbsolutePath(), content );
+        FileUtils.fileWrite( sampleResource.getAbsolutePath(), content );
+        String filterContent = "resource_value_1=this_is_filtered\n";
+        filterContent += "resource_value_2=this_is_filtered";
+        FileUtils.fileWrite( filterFile.getAbsolutePath(), filterContent );
+
+        mojo.execute();
+
+        // validate filtered file
+        content = FileUtils.fileRead( expectedResourceWDirFile );
+        reader = new BufferedReader( new StringReader( content ) );
+
+        assertEquals( "error in filtering using System Properties", comment, reader.readLine() );
+
+        assertEquals( "error in filtering using System properties", "system_key_1=" + System.getProperty( "user.dir" ),
+                      reader.readLine() );
+        assertEquals( "error in filtering using System properties", "system_key_2=" + System.getProperty( "user.dir" ),
+                      reader.readLine() );
+
+        assertEquals( "error in filtering using project properties", "project_key_1=i_think_so", reader.readLine() );
+        assertEquals( "error in filtering using project properties", "project_key_2=i_think_so", reader.readLine() );
+
+        assertEquals( "error in filtering using project properties", "project_name_1=Test Project ", reader.readLine() );
+        assertEquals( "error in filtering using project properties", "project_name_2=Test Project ", reader.readLine() );
+
+        assertEquals( "error in filtering using System properties", "system_property_1=new-system-property-value",
+                      reader.readLine() );
+        assertEquals( "error in filtering using System properties", "system_property_2=new-system-property-value",
+                      reader.readLine() );
+
+        assertEquals( "error in filtering using filter files", "resource_key_1=this_is_filtered", reader.readLine() );
+        assertEquals( "error in filtering using filter files", "resource_key_2=this_is_filtered", reader.readLine() );
+
+        // house keeping
+        expectedWebSourceFile.delete();
+        expectedWebSource2File.delete();
+        expectedResourceFile.delete();
+        expectedResourceWDirFile.delete();
+    }
+
+}
diff --git a/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/WarExplodedMojoTest.java b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/WarExplodedMojoTest.java
new file mode 100644
index 000000000..22ff280de
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/WarExplodedMojoTest.java
@@ -0,0 +1,1055 @@
+package org.apache.maven.plugins.war;
+
+/*
+ * 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.
+ */
+
+import static org.junit.Assert.assertNotEquals;
+
+import org.apache.maven.artifact.handler.ArtifactHandler;
+import org.apache.maven.plugin.testing.stubs.ArtifactStub;
+import org.apache.maven.plugins.war.stub.AarArtifactStub;
+import org.apache.maven.plugins.war.stub.EJBArtifactStub;
+import org.apache.maven.plugins.war.stub.EJBArtifactStubWithClassifier;
+import org.apache.maven.plugins.war.stub.EJBClientArtifactStub;
+import org.apache.maven.plugins.war.stub.IncludeExcludeWarArtifactStub;
+import org.apache.maven.plugins.war.stub.JarArtifactStub;
+import org.apache.maven.plugins.war.stub.MarArtifactStub;
+import org.apache.maven.plugins.war.stub.MavenProjectArtifactsStub;
+import org.apache.maven.plugins.war.stub.MavenProjectBasicStub;
+import org.apache.maven.plugins.war.stub.PARArtifactStub;
+import org.apache.maven.plugins.war.stub.ResourceStub;
+import org.apache.maven.plugins.war.stub.TLDArtifactStub;
+import org.apache.maven.plugins.war.stub.WarArtifactStub;
+import org.apache.maven.plugins.war.stub.XarArtifactStub;
+import org.codehaus.plexus.util.FileUtils;
+
+import java.io.File;
+import java.text.SimpleDateFormat;
+import java.util.LinkedList;
+import java.util.Locale;
+
+public class WarExplodedMojoTest
+    extends AbstractWarExplodedMojoTest
+{
+
+    protected File getPomFile()
+    {
+        return new File( getBasedir(), "/target/test-classes/unit/warexplodedmojo/plugin-config.xml" );
+    }
+
+    protected File getTestDirectory()
+    {
+        return new File( getBasedir(), "target/test-classes/unit/warexplodedmojo/test-dir" );
+    }
+
+    /**
+     * @throws Exception in case of an error.
+     */
+    public void testSimpleExplodedWar()
+        throws Exception
+    {
+        // setup test data
+        String testId = "SimpleExplodedWar";
+        MavenProjectBasicStub project = new MavenProjectBasicStub();
+        File webAppSource = createWebAppSource( testId );
+        File classesDir = createClassesDir( testId, false );
+        File webAppResource = new File( getTestDirectory(), testId + "-resources" );
+        File webAppDirectory = new File( getTestDirectory(), testId );
+        File sampleResource = new File( webAppResource, "pix/panis_na.jpg" );
+        ResourceStub[] resources = new ResourceStub[] { new ResourceStub() };
+
+        createFile( sampleResource );
+
+        assertTrue( "sampeResource not found", sampleResource.exists() );
+
+        // configure mojo
+        resources[0].setDirectory( webAppResource.getAbsolutePath() );
+        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
+        setVariableValueToObject( mojo, "webResources", resources );
+        mojo.execute();
+
+        // validate operation
+        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
+        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
+        File expectedWebResourceFile = new File( webAppDirectory, "pix/panis_na.jpg" );
+        File expectedWEBINFDir = new File( webAppDirectory, "WEB-INF" );
+        File expectedMETAINFDir = new File( webAppDirectory, "META-INF" );
+
+        assertTrue( "source files not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
+        assertTrue( "source files not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
+        assertTrue( "resources doesn't exist: " + expectedWebResourceFile, expectedWebResourceFile.exists() );
+        assertTrue( "WEB-INF not found", expectedWEBINFDir.exists() );
+        assertTrue( "META-INF not found", expectedMETAINFDir.exists() );
+
+        // house keeping
+        expectedWebSourceFile.delete();
+        expectedWebSource2File.delete();
+        expectedWebResourceFile.delete();
+    }
+
+    /**
+     * @throws Exception in case of an error.
+     */
+    public void testSimpleExplodedWarWTargetPath()
+        throws Exception
+    {
+        // setup test data
+        String testId = "SimpleExplodedWar";
+        MavenProjectBasicStub project = new MavenProjectBasicStub();
+        File webAppSource = createWebAppSource( testId );
+        File classesDir = createClassesDir( testId, false );
+        File webAppResource = new File( getTestDirectory(), "resources" );
+        File webAppDirectory = new File( getTestDirectory(), testId );
+        File sampleResource = new File( webAppResource, "pix/panis_na.jpg" );
+        ResourceStub[] resources = new ResourceStub[] { new ResourceStub() };
+
+        createFile( sampleResource );
+
+        // configure mojo
+        resources[0].setDirectory( webAppResource.getAbsolutePath() );
+        resources[0].setTargetPath( "targetPath" );
+        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
+        setVariableValueToObject( mojo, "webResources", resources );
+        mojo.execute();
+
+        // validate operation
+        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
+        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
+        File expectedWebResourceFile = new File( webAppDirectory, "targetPath/pix/panis_na.jpg" );
+        File expectedWEBINFDir = new File( webAppDirectory, "WEB-INF" );
+        File expectedMETAINFDir = new File( webAppDirectory, "META-INF" );
+
+        assertTrue( "source files not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
+        assertTrue( "source files not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
+        assertTrue( "resources doesn't exist: " + expectedWebResourceFile, expectedWebResourceFile.exists() );
+        assertTrue( "WEB-INF not found", expectedWEBINFDir.exists() );
+        assertTrue( "META-INF not found", expectedMETAINFDir.exists() );
+
+        // house keeping
+        expectedWebSourceFile.delete();
+        expectedWebSource2File.delete();
+        expectedWebResourceFile.delete();
+    }
+
+    /**
+     * @throws Exception in case of an error.
+     */
+    public void testExplodedWar_WithCustomWebXML()
+        throws Exception
+    {
+        // setup test data
+        String testId = "ExplodedWar_WithCustomWebXML";
+        MavenProjectBasicStub project = new MavenProjectBasicStub();
+        File webAppSource = createWebAppSource( testId );
+        File classesDir = createClassesDir( testId, true );
+        File xmlSource = createXMLConfigDir( testId, new String[] { "web.xml" } );
+        File webAppDirectory = new File( getTestDirectory(), testId );
+
+        // configure mojo
+        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
+        mojo.setWebXml( new File( xmlSource, "web.xml" ) );
+        mojo.execute();
+
+        // validate operation
+        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
+        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
+        File expectedWEBXMLFile = new File( webAppDirectory, "WEB-INF/web.xml" );
+        File expectedMETAINFDir = new File( webAppDirectory, "META-INF" );
+
+        assertTrue( "source files not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
+        assertTrue( "source files not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
+        assertTrue( "WEB XML not found: " + expectedWEBXMLFile.toString(), expectedWEBXMLFile.exists() );
+        assertTrue( "META-INF not found", expectedMETAINFDir.exists() );
+        assertEquals( "WEB XML not correct", mojo.getWebXml().toString(), FileUtils.fileRead( expectedWEBXMLFile ) );
+
+        // house keeping
+        expectedWebSourceFile.delete();
+        expectedWebSource2File.delete();
+        expectedWEBXMLFile.delete();
+        expectedMETAINFDir.delete();
+    }
+
+    /**
+     * @throws Exception in case of an error.
+     */
+    public void testExplodedWar_WithContainerConfigXML()
+        throws Exception
+    {
+        // setup test data
+        String testId = "ExplodedWar_WithContainerConfigXML";
+        MavenProjectBasicStub project = new MavenProjectBasicStub();
+        File classesDir = createClassesDir( testId, true );
+        File webAppSource = createWebAppSource( testId );
+        File xmlSource = createXMLConfigDir( testId, new String[] { "config.xml" } );
+        File webAppDirectory = new File( getTestDirectory(), testId );
+
+        // configure mojo
+        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
+        mojo.setContainerConfigXML( new File( xmlSource, "config.xml" ) );
+        mojo.execute();
+
+        // validate operation
+        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
+        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
+        File expectedContainerConfigXMLFile = new File( webAppDirectory, "META-INF/config.xml" );
+        File expectedWEBINFDir = new File( webAppDirectory, "WEB-INF" );
+
+        assertTrue( "source files not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
+        assertTrue( "source files not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
+        assertTrue( "WEB-INF not found", expectedWEBINFDir.exists() );
+        assertTrue( "Container Config XML not found:" + expectedContainerConfigXMLFile.toString(),
+                    expectedContainerConfigXMLFile.exists() );
+
+        // house keeping
+        expectedWebSourceFile.delete();
+        expectedWebSource2File.delete();
+        expectedContainerConfigXMLFile.delete();
+        expectedWEBINFDir.delete();
+    }
+
+    /**
+     * @throws Exception in case of an error.
+     */
+    public void testExplodedWar_WithSimpleExternalWARFile()
+        throws Exception
+    {
+        // setup test data
+        MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
+        WarArtifactStub warArtifact = new WarArtifactStub( getBasedir() );
+
+        String testId = "ExplodedWar_WithSimpleExternalWARFile";
+        File webAppDirectory = new File( getTestDirectory(), testId );
+        File webAppSource = createWebAppSource( testId );
+        File classesDir = createClassesDir( testId, true );
+        File workDirectory = new File( getTestDirectory(), "/war/work-" + testId );
+        File simpleWarFile = warArtifact.getFile();
+
+        assertTrue( "simple war not found: " + simpleWarFile.toString(), simpleWarFile.exists() );
+
+        createDir( workDirectory );
+
+        // configure mojo
+        project.addArtifact( warArtifact );
+        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
+        setVariableValueToObject( mojo, "workDirectory", workDirectory );
+        mojo.execute();
+
+        // validate operation - META-INF is automatically excluded so remove the file from the list
+        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
+        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
+        File expectedWEBXMLFile = new File( webAppDirectory, "WEB-INF/web.xml" );
+        File expectedWARFile = new File( webAppDirectory, "/org/sample/company/test.jsp" );
+
+        assertTrue( "source files not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
+        assertTrue( "source files not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
+        // check simple.war in the unit test dir under resources to verify the list of files
+        assertTrue( "web xml not found: " + expectedWEBXMLFile.toString(), expectedWEBXMLFile.exists() );
+        assertTrue( "war file not found: " + expectedWARFile.toString(), expectedWARFile.exists() );
+
+        // house keeping
+        expectedWebSourceFile.delete();
+        expectedWebSource2File.delete();
+        expectedWEBXMLFile.delete();
+        expectedWARFile.delete();
+    }
+
+    /**
+     * Merge a dependent WAR when a file in the war source directory overrides one found in the WAR.
+     * @throws Exception in case of an error.
+     */
+    public void testExplodedWarMergeWarLocalFileOverride()
+        throws Exception
+    {
+        // setup test data
+        MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
+        WarArtifactStub warArtifact = new WarArtifactStub( getBasedir() );
+
+        String testId = "testExplodedWarMergeWarLocalFileOverride";
+        File webAppDirectory = new File( getTestDirectory(), testId );
+        File webAppSource = getWebAppSource( testId );
+        File simpleJSP = new File( webAppSource, "org/sample/company/test.jsp" );
+        createFile( simpleJSP );
+
+        File workDirectory = new File( getTestDirectory(), "/war/work-" + testId );
+        createDir( workDirectory );
+
+        File classesDir = createClassesDir( testId, true );
+
+        // configure mojo
+        project.addArtifact( warArtifact );
+        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
+        setVariableValueToObject( mojo, "workDirectory", workDirectory );
+        mojo.execute();
+
+        // validate operation
+        File expectedFile = new File( webAppDirectory, "/org/sample/company/test.jsp" );
+
+        assertTrue( "file not found: " + expectedFile.toString(), expectedFile.exists() );
+        assertEquals( "file incorrect", simpleJSP.toString(), FileUtils.fileRead( expectedFile ) );
+
+        // check when the merged war file is newer - so set an old time on the local file
+        long time = new SimpleDateFormat( "yyyy-MM-dd", Locale.US ).parse( "2005-1-1" ).getTime();
+        simpleJSP.setLastModified( time );
+        expectedFile.setLastModified( time );
+
+        project.addArtifact( warArtifact );
+        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
+        setVariableValueToObject( mojo, "workDirectory", workDirectory );
+        mojo.execute();
+
+        assertTrue( "file not found: " + expectedFile.toString(), expectedFile.exists() );
+        assertEquals( "file incorrect", simpleJSP.toString(), FileUtils.fileRead( expectedFile ) );
+
+        // house keeping
+        expectedFile.delete();
+    }
+
+    // The last modified thingy behavior is not applicable anymore. This is the only test that
+    // has been removed.
+    // /**
+    // * Merge a dependent WAR that gets updated since the last run.
+    // */
+    // public void testExplodedWarMergeWarUpdated()
+    // throws Exception
+    // {
+    // // setup test data
+    // MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
+    // WarArtifactStub warArtifact = new WarArtifactStub( getBasedir() );
+    //
+    // String testId = "testExplodedWarMergeWarUpdated";
+    // File webAppDirectory = new File( getTestDirectory(), testId );
+    // FileUtils.deleteDirectory( webAppDirectory );
+    //
+    // File webAppSource = getWebAppSource( testId );
+    //
+    // File workDirectory = new File( getTestDirectory(), "/war/work-" + testId );
+    // createDir( workDirectory );
+    //
+    // File classesDir = createClassesDir( testId, true );
+    //
+    // // configure mojo
+    // project.addArtifact( warArtifact );
+    // this.configureMojo( mojo, new LinkedList(), classesDir, webAppSource, webAppDirectory, project );
+    // setVariableValueToObject( mojo, "workDirectory", workDirectory );
+    // mojo.execute();
+    //
+    // // validate operation
+    // File expectedFile = new File( webAppDirectory, "/org/sample/company/test.jsp" );
+    //
+    // assertTrue( "file not found: " + expectedFile.toString(), expectedFile.exists() );
+    // assertEquals( "file incorrect", "", FileUtils.fileRead( expectedFile ) );
+    //
+    // // update file, so the local one is older
+    // warArtifact.setFile( new File( warArtifact.getFile().getParentFile(), "simple-updated.war" ) );
+    //
+    // mojo.execute();
+    //
+    // assertTrue( "file not found: " + expectedFile.toString(), expectedFile.exists() );
+    // assertEquals( "file incorrect", "updated\n", FileUtils.fileRead( expectedFile ) );
+    //
+    // // update file, so the local one is newer
+    // warArtifact.setFile( new File( warArtifact.getFile().getParentFile(), "simple.war" ) );
+    //
+    // mojo.execute();
+    //
+    // assertTrue( "file not found: " + expectedFile.toString(), expectedFile.exists() );
+    // assertEquals( "file incorrect", "updated\n", FileUtils.fileRead( expectedFile ) );
+    //
+    // // house keeping
+    // expectedFile.delete();
+    // }
+
+    /**
+     * @throws Exception in case of an error.
+     */
+    public void testExplodedWar_WithEJB()
+        throws Exception
+    {
+        // setup test data
+        String testId = "ExplodedWar_WithEJB";
+        MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
+        File webAppDirectory = new File( getTestDirectory(), testId );
+        File webAppSource = createWebAppSource( testId );
+        File classesDir = createClassesDir( testId, true );
+        EJBArtifactStub ejbArtifact = new EJBArtifactStub( getBasedir() );
+        File ejbFile = ejbArtifact.getFile();
+
+        assertTrue( "ejb jar not found: " + ejbFile.toString(), ejbFile.exists() );
+
+        // configure mojo
+        project.addArtifact( ejbArtifact );
+        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
+        mojo.execute();
+
+        // validate operation
+        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
+        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
+        // final name form is <artifactId>-<version>.<type>
+        File expectedEJBArtifact = new File( webAppDirectory, "WEB-INF/lib/ejbartifact-0.0-Test.jar" );
+        // File expectedEJBArtifact = new File( webAppDirectory, "WEB-INF/lib/ejbartifact-0.0-Test.jar" );
+
+        assertTrue( "source files not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
+        assertTrue( "source files not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
+        assertTrue( "ejb artifact not found: " + expectedEJBArtifact.toString(), expectedEJBArtifact.exists() );
+
+        // house keeping
+        expectedWebSourceFile.delete();
+        expectedWebSource2File.delete();
+        expectedEJBArtifact.delete();
+    }
+
+    public void testExplodedWarWithJar()
+        throws Exception
+    {
+        // setup test data
+        String testId = "ExplodedWarWithJar";
+        MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
+        File webAppDirectory = new File( getTestDirectory(), testId );
+        File webAppSource = createWebAppSource( testId );
+        File classesDir = createClassesDir( testId, true );
+        ArtifactHandler artifactHandler = (ArtifactHandler) lookup( ArtifactHandler.ROLE, "jar" );
+        ArtifactStub jarArtifact = new JarArtifactStub( getBasedir(), artifactHandler );
+        File jarFile = jarArtifact.getFile();
+
+        assertTrue( "jar not found: " + jarFile.toString(), jarFile.exists() );
+
+        // configure mojo
+        project.addArtifact( jarArtifact );
+        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
+        mojo.execute();
+
+        // validate operation
+        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
+        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
+        // final name form is <artifactId>-<version>.<type>
+        File expectedJarArtifact = new File( webAppDirectory, "WEB-INF/lib/jarartifact-0.0-Test.jar" );
+
+        assertTrue( "source files not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
+        assertTrue( "source files not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
+        assertTrue( "jar artifact not found: " + expectedJarArtifact.toString(), expectedJarArtifact.exists() );
+
+        // house keeping
+        expectedWebSourceFile.delete();
+        expectedWebSource2File.delete();
+        expectedJarArtifact.delete();
+    }
+
+    /**
+     * @throws Exception in case of an error.
+     */
+    public void testExplodedWar_WithEJBClient()
+        throws Exception
+    {
+        // setup test data
+        String testId = "ExplodedWar_WithEJB";
+        MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
+        File webAppDirectory = new File( getTestDirectory(), testId );
+        File webAppSource = createWebAppSource( testId );
+        File classesDir = createClassesDir( testId, true );
+        EJBClientArtifactStub ejbArtifact = new EJBClientArtifactStub( getBasedir() );
+        File ejbFile = ejbArtifact.getFile();
+
+        assertTrue( "ejb jar not found: " + ejbFile.toString(), ejbFile.exists() );
+
+        // configure mojo
+        project.addArtifact( ejbArtifact );
+        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
+        mojo.execute();
+
+        // validate operation
+        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
+        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
+        // final name form is <artifactId>-<version>.<type>
+        File expectedEJBArtifact = new File( webAppDirectory, "WEB-INF/lib/ejbclientartifact-0.0-Test-client.jar" );
+
+        assertTrue( "source files not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
+        assertTrue( "source files not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
+        assertTrue( "ejb artifact not found: " + expectedEJBArtifact.toString(), expectedEJBArtifact.exists() );
+
+        // house keeping
+        expectedWebSourceFile.delete();
+        expectedWebSource2File.delete();
+        expectedEJBArtifact.delete();
+    }
+
+    /**
+     * @throws Exception in case of an error.
+     */
+    public void testExplodedWar_WithTLD()
+        throws Exception
+    {
+        // setup test data
+        String testId = "ExplodedWar_WithTLD";
+        MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
+        File webAppDirectory = new File( getTestDirectory(), testId );
+        File webAppSource = createWebAppSource( testId );
+        File classesDir = createClassesDir( testId, true );
+        TLDArtifactStub tldArtifact = new TLDArtifactStub( getBasedir() );
+        File tldFile = tldArtifact.getFile();
+
+        assertTrue( "tld jar not found: " + tldFile.getAbsolutePath(), tldFile.exists() );
+
+        // configure mojo
+        project.addArtifact( tldArtifact );
+        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
+        mojo.execute();
+
+        // validate operation
+        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
+        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
+        // final name form is <artifactId>-<version>.<type>
+        File expectedTLDArtifact = new File( webAppDirectory, "WEB-INF/tld/tldartifact-0.0-Test.tld" );
+
+        assertTrue( "source files not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
+        assertTrue( "source files not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
+        assertTrue( "tld artifact not found: " + expectedTLDArtifact.toString(), expectedTLDArtifact.exists() );
+
+        // house keeping
+        expectedWebSourceFile.delete();
+        expectedWebSource2File.delete();
+        expectedTLDArtifact.delete();
+    }
+
+    /**
+     * @throws Exception in case of an error.
+     */
+    public void testExplodedWar_WithPAR()
+        throws Exception
+    {
+        // setup test data
+        String testId = "ExplodedWar_WithPAR";
+        MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
+        File webAppDirectory = new File( getTestDirectory(), testId );
+        File webAppSource = createWebAppSource( testId );
+        File classesDir = createClassesDir( testId, true );
+        PARArtifactStub parartifact = new PARArtifactStub( getBasedir() );
+        File parFile = parartifact.getFile();
+
+        assertTrue( "par not found: " + parFile.getAbsolutePath(), parFile.exists() );
+
+        // configure mojo
+        project.addArtifact( parartifact );
+        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
+        mojo.execute();
+
+        // validate operation
+        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
+        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
+        // final name form is <artifactId>-<version>.<type>
+        File expectedPARArtifact = new File( webAppDirectory, "WEB-INF/lib/parartifact-0.0-Test.jar" );
+
+        assertTrue( "source files not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
+        assertTrue( "source files not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
+        assertTrue( "par artifact not found: " + expectedPARArtifact.toString(), expectedPARArtifact.exists() );
+
+        // house keeping
+        expectedWebSourceFile.delete();
+        expectedWebSource2File.delete();
+        expectedPARArtifact.delete();
+    }
+
+    /**
+     * @throws Exception in case of an error.
+     */
+    public void testExplodedWarWithAar()
+        throws Exception
+    {
+        // setup test data
+        String testId = "ExplodedWarWithAar";
+        MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
+        File webAppDirectory = new File( getTestDirectory(), testId );
+        File webAppSource = createWebAppSource( testId );
+        File classesDir = createClassesDir( testId, true );
+        // Fake here since the aar artifact handler does not exist: no biggie
+        ArtifactHandler artifactHandler = (ArtifactHandler) lookup( ArtifactHandler.ROLE, "jar" );
+        ArtifactStub aarArtifact = new AarArtifactStub( getBasedir(), artifactHandler );
+        File aarFile = aarArtifact.getFile();
+
+        assertTrue( "jar not found: " + aarFile.toString(), aarFile.exists() );
+
+        // configure mojo
+        project.addArtifact( aarArtifact );
+        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
+        mojo.execute();
+
+        // validate operation
+        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
+        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
+        // final name form is <artifactId>-<version>.<type>
+        File expectedJarArtifact = new File( webAppDirectory, "WEB-INF/services/aarartifact-0.0-Test.jar" );
+
+        assertTrue( "source files not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
+        assertTrue( "source files not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
+        assertTrue( "jar artifact not found: " + expectedJarArtifact.toString(), expectedJarArtifact.exists() );
+
+        // house keeping
+        expectedWebSourceFile.delete();
+        expectedWebSource2File.delete();
+        expectedJarArtifact.delete();
+    }
+
+    /**
+     * @throws Exception in case of an error.
+     */
+    public void testExplodedWarWithMar()
+        throws Exception
+    {
+        // setup test data
+        String testId = "ExplodedWarWithMar";
+        MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
+        File webAppDirectory = new File( getTestDirectory(), testId );
+        File webAppSource = createWebAppSource( testId );
+        File classesDir = createClassesDir( testId, true );
+        // Fake here since the mar artifact handler does not exist: no biggie
+        ArtifactHandler artifactHandler = (ArtifactHandler) lookup( ArtifactHandler.ROLE, "jar" );
+        ArtifactStub marArtifact = new MarArtifactStub( getBasedir(), artifactHandler );
+        File marFile = marArtifact.getFile();
+
+        assertTrue( "jar not found: " + marFile.toString(), marFile.exists() );
+
+        // configure mojo
+        project.addArtifact( marArtifact );
+        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
+        mojo.execute();
+
+        // validate operation
+        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
+        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
+        // final name form is <artifactId>-<version>.<type>
+        File expectedJarArtifact = new File( webAppDirectory, "WEB-INF/modules/marartifact-0.0-Test.jar" );
+
+        assertTrue( "source files not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
+        assertTrue( "source files not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
+        assertTrue( "jar artifact not found: " + expectedJarArtifact.toString(), expectedJarArtifact.exists() );
+
+        // house keeping
+        expectedWebSourceFile.delete();
+        expectedWebSource2File.delete();
+        expectedJarArtifact.delete();
+    }
+
+    /**
+     * @throws Exception in case of an error.
+     */
+    public void testExplodedWarWithXar()
+        throws Exception
+    {
+        // setup test data
+        String testId = "ExplodedWarWithXar";
+        MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
+        File webAppDirectory = new File( getTestDirectory(), testId );
+        File webAppSource = createWebAppSource( testId );
+        File classesDir = createClassesDir( testId, true );
+        // Fake here since the xar artifact handler does not exist: no biggie
+        ArtifactHandler artifactHandler = (ArtifactHandler) lookup( ArtifactHandler.ROLE, "jar" );
+        ArtifactStub xarArtifact = new XarArtifactStub( getBasedir(), artifactHandler );
+        File xarFile = xarArtifact.getFile();
+
+        assertTrue( "jar not found: " + xarFile.toString(), xarFile.exists() );
+
+        // configure mojo
+        project.addArtifact( xarArtifact );
+        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
+        mojo.execute();
+
+        // validate operation
+        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
+        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
+        // final name form is <artifactId>-<version>.<type>
+        File expectedJarArtifact = new File( webAppDirectory, "WEB-INF/extensions/xarartifact-0.0-Test.jar" );
+
+        assertTrue( "source files not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
+        assertTrue( "source files not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
+        assertTrue( "jar artifact not found: " + expectedJarArtifact.toString(), expectedJarArtifact.exists() );
+
+        // house keeping
+        expectedWebSourceFile.delete();
+        expectedWebSource2File.delete();
+        expectedJarArtifact.delete();
+    }
+
+    /**
+     * @throws Exception in case of an error.
+     */
+    public void testExplodedWar_WithDuplicateDependencies()
+        throws Exception
+    {
+        // setup test data
+        String testId = "ExplodedWar_WithDuplicateDependencies";
+        MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
+        File webAppDirectory = new File( getTestDirectory(), testId );
+        File webAppSource = createWebAppSource( testId );
+        File classesDir = createClassesDir( testId, true );
+        EJBArtifactStub ejbArtifact = new EJBArtifactStub( getBasedir() );
+        EJBArtifactStub ejbArtifactDup = new EJBArtifactStub( getBasedir() );
+        File ejbFile = ejbArtifact.getFile();
+
+        // ejbArtifact has a hard coded file, only one assert is needed
+        assertTrue( "ejb not found: " + ejbFile.getAbsolutePath(), ejbFile.exists() );
+
+        // configure mojo
+        ejbArtifact.setGroupId( "org.sample.ejb" );
+        ejbArtifactDup.setGroupId( "org.dup.ejb" );
+        project.addArtifact( ejbArtifact );
+        project.addArtifact( ejbArtifactDup );
+        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
+        mojo.execute();
+
+        // validate operation
+        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
+        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
+        // final name form is <artifactId>-<version>.<type>
+        File expectedEJBArtifact = new File( webAppDirectory, "WEB-INF/lib/org.sample.ejb-ejbartifact-0.0-Test.jar" );
+        File expectedEJBDupArtifact = new File( webAppDirectory, "WEB-INF/lib/org.dup.ejb-ejbartifact-0.0-Test.jar" );
+
+        assertTrue( "source files not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
+        assertTrue( "source files not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
+        assertTrue( "ejb artifact not found: " + expectedEJBArtifact.toString(), expectedEJBArtifact.exists() );
+        assertTrue( "ejb dup artifact not found: " + expectedEJBDupArtifact.toString(), expectedEJBDupArtifact.exists() );
+
+        // house keeping
+        expectedWebSourceFile.delete();
+        expectedWebSource2File.delete();
+        expectedEJBArtifact.delete();
+        expectedEJBDupArtifact.delete();
+    }
+
+    /**
+     * @throws Exception in case of an error.
+     */
+    public void testExplodedWar_DuplicateWithClassifier()
+        throws Exception
+    {
+        // setup test data
+        String testId = "ExplodedWar_DuplicateWithClassifier";
+        MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
+        File webAppDirectory = new File( getTestDirectory(), testId );
+        File webAppSource = createWebAppSource( testId );
+        File classesDir = createClassesDir( testId, true );
+        EJBArtifactStub ejbArtifact = new EJBArtifactStub( getBasedir() );
+        EJBArtifactStubWithClassifier ejbArtifactDup = new EJBArtifactStubWithClassifier( getBasedir() );
+
+        File ejbFile = ejbArtifact.getFile();
+
+        // ejbArtifact has a hard coded file, only one assert is needed
+        assertTrue( "ejb not found: " + ejbFile.getAbsolutePath(), ejbFile.exists() );
+
+        // configure mojo
+
+        ejbArtifact.setGroupId( "org.sample.ejb" );
+        ejbArtifactDup.setGroupId( "org.sample.ejb" );
+
+        ejbArtifactDup.setClassifier( "classifier" );
+
+        project.addArtifact( ejbArtifact );
+        project.addArtifact( ejbArtifactDup );
+
+        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
+        mojo.execute();
+
+        // validate operation
+        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
+        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
+        // final name form is <artifactId>-<version>.<type>
+        File expectedEJBArtifact = new File( webAppDirectory, "WEB-INF/lib/ejbartifact-0.0-Test.jar" );
+        File expectedEJBDupArtifact = new File( webAppDirectory, "WEB-INF/lib/ejbartifact-0.0-Test-classifier.jar" );
+
+        assertTrue( "source files not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
+        assertTrue( "source files not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
+        assertTrue( "ejb artifact not found: " + expectedEJBArtifact.toString(), expectedEJBArtifact.exists() );
+        assertTrue( "ejb dup artifact not found: " + expectedEJBDupArtifact.toString(), expectedEJBDupArtifact.exists() );
+
+        // house keeping
+        expectedWebSourceFile.delete();
+        expectedWebSource2File.delete();
+        expectedEJBArtifact.delete();
+        expectedEJBDupArtifact.delete();
+    }
+
+    /**
+     * @throws Exception in case of an error.
+     */
+    public void testExplodedWar_WithClasses()
+        throws Exception
+    {
+        // setup test data
+        String testId = "ExplodedWar_WithClasses";
+        MavenProjectBasicStub project = new MavenProjectBasicStub();
+        File webAppDirectory = new File( getTestDirectory(), testId );
+        File webAppSource = createWebAppSource( testId );
+        File classesDir = createClassesDir( testId, false );
+
+        // configure mojo
+        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
+        mojo.execute();
+
+        // validate operation
+        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
+        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
+        // final name form is <artifactId>-<version>.<type>
+        File expectedClass = new File( webAppDirectory, "WEB-INF/classes/sample-servlet.class" );
+
+        assertTrue( "source files not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
+        assertTrue( "source files not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
+        assertTrue( "classes not found: " + expectedClass.toString(), expectedClass.exists() );
+
+        // house keeping
+        expectedWebSourceFile.delete();
+        expectedWebSource2File.delete();
+        expectedClass.delete();
+    }
+
+    /**
+     * @throws Exception in case of an error.
+     */
+    public void testExplodedWar_WithSourceIncludeExclude()
+        throws Exception
+    {
+        // setup test data
+        String testId = "ExplodedWar_WithSourceIncludeExclude";
+        MavenProjectBasicStub project = new MavenProjectBasicStub();
+        File webAppSource = createWebAppSource( testId );
+        File classesDir = createClassesDir( testId, true );
+        File webAppDirectory = new File( getTestDirectory(), testId );
+
+        // configure mojo
+        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
+        setVariableValueToObject( mojo, "warSourceIncludes", "**/*sit.jsp" );
+        setVariableValueToObject( mojo, "warSourceExcludes", "**/last*.*" );
+        mojo.execute();
+
+        // validate operation
+        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
+        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
+        File expectedWEBXMLDir = new File( webAppDirectory, "WEB-INF" );
+        File expectedMETAINFDir = new File( webAppDirectory, "META-INF" );
+
+        assertTrue( "source files not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
+        assertFalse( "source files found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
+        assertTrue( "WEB XML not found: " + expectedWEBXMLDir.toString(), expectedWEBXMLDir.exists() );
+        assertTrue( "META-INF not found", expectedMETAINFDir.exists() );
+
+        // house keeping
+        expectedWebSourceFile.delete();
+        expectedWebSource2File.delete();
+        expectedWEBXMLDir.delete();
+        expectedMETAINFDir.delete();
+    }
+
+    /**
+     * @throws Exception in case of an error.
+     */
+    public void testExplodedWar_WithWarDependencyIncludeExclude()
+        throws Exception
+    {
+        // setup test data
+        String testId = "ExplodedWar_WithWarDependencyIncludeExclude";
+        MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
+        IncludeExcludeWarArtifactStub includeexcludeWarArtifact = new IncludeExcludeWarArtifactStub( getBasedir() );
+        File webAppDirectory = new File( getTestDirectory(), testId );
+        File webAppSource = createWebAppSource( testId );
+        File classesDir = createClassesDir( testId, true );
+        File workDirectory = new File( getTestDirectory(), "/war/work-" + testId );
+        File includeExcludeWarFile = includeexcludeWarArtifact.getFile();
+
+        assertTrue( "war not found: " + includeExcludeWarFile.toString(), includeExcludeWarFile.exists() );
+
+        createDir( workDirectory );
+
+        // configure mojo
+        project.addArtifact( includeexcludeWarArtifact );
+        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
+        setVariableValueToObject( mojo, "dependentWarIncludes", "**/*Include.jsp,**/*.xml" );
+        setVariableValueToObject( mojo, "dependentWarExcludes", "**/*Exclude*,**/MANIFEST.MF" );
+        setVariableValueToObject( mojo, "workDirectory", workDirectory );
+        mojo.execute();
+
+        // validate operation
+        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
+        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
+        File expectedManifestFile = new File( webAppDirectory, "META-INF/MANIFEST.MF" );
+        File expectedWEBXMLFile = new File( webAppDirectory, "WEB-INF/web.xml" );
+        File expectedIncludedWARFile = new File( webAppDirectory, "/org/sample/company/testInclude.jsp" );
+        File expectedExcludedWarfile = new File( webAppDirectory, "/org/sample/companyExclude/test.jsp" );
+
+        assertTrue( "source files not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
+        assertTrue( "source files not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
+        // check include-exclude.war in the unit test dir under resources to verify the list of files
+        assertTrue( "web xml not found: " + expectedWEBXMLFile.toString(), expectedWEBXMLFile.exists() );
+        assertFalse( "manifest file found: " + expectedManifestFile.toString(), expectedManifestFile.exists() );
+        assertTrue( "war file not found: " + expectedIncludedWARFile.toString(), expectedIncludedWARFile.exists() );
+        assertFalse( "war file not found: " + expectedExcludedWarfile.toString(), expectedExcludedWarfile.exists() );
+
+        // house keeping
+        expectedWebSourceFile.delete();
+        expectedWebSource2File.delete();
+        expectedManifestFile.delete();
+        expectedWEBXMLFile.delete();
+        expectedIncludedWARFile.delete();
+        expectedExcludedWarfile.delete();
+    }
+
+    /**
+     * @throws Exception in case of an error.
+     */
+    public void testExplodedWarWithSourceModificationCheck()
+        throws Exception
+    {
+        // setup test data
+        String testId = "ExplodedWarWithSourceModificationCheck";
+        MavenProjectBasicStub project = new MavenProjectBasicStub();
+        File webAppSource = createWebAppSource( testId );
+        File classesDir = createClassesDir( testId, false );
+        File webAppDirectory = new File( getTestDirectory(), testId );
+
+        // configure mojo
+        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
+
+        // destination file is already created manually containing an "error" string
+        // source is newer than the destination file
+        mojo.execute();
+
+        // validate operation
+
+        File expectedWEBINFDir = new File( webAppDirectory, "WEB-INF" );
+        File expectedMETAINFDir = new File( webAppDirectory, "META-INF" );
+        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
+        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
+
+        assertTrue( "source files not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
+        assertTrue( "source files not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
+        assertTrue( "WEB-INF not found", expectedWEBINFDir.exists() );
+        assertTrue( "META-INF not found", expectedMETAINFDir.exists() );
+
+        // 1st phase destination is older than source
+        // destination starts with a value of error replaced with a blank source
+        assertNotEquals( "source files not updated with new copy: " + expectedWebSourceFile.toString(),
+                "error", FileUtils.fileRead( expectedWebSourceFile ) );
+
+        // TODO: uncomment when lastModified problem is resolved
+        // FileWriter writer = new FileWriter(expectedWebSourceFile);
+        //
+        // // 2nd phase destination is newer than source
+        // // destination should not be replaced with an blank source
+        // writer.write("newdata");
+        // mojo.execute();
+        // reader = new FileReader(expectedWebSourceFile);
+        // reader.read(data);
+        // assertTrue("source file updated with old copy: "
+        // +expectedWebSourceFile.toString(),String.valueOf(data).equals("newdata") ); }
+
+        // house keeping
+        expectedWEBINFDir.delete();
+        expectedMETAINFDir.delete();
+        expectedWebSourceFile.delete();
+        expectedWebSource2File.delete();
+    }
+
+    /**
+     * @throws Exception in case of an error.
+     */
+    public void testExplodedWarWithOutputFileNameMapping()
+        throws Exception
+    {
+        // setup test data
+        String testId = "ExplodedWarWithFileNameMapping";
+        MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
+        File webAppDirectory = new File( getTestDirectory(), testId );
+        File webAppSource = createWebAppSource( testId );
+        File classesDir = createClassesDir( testId, true );
+        ArtifactHandler artifactHandler = (ArtifactHandler) lookup( ArtifactHandler.ROLE, "jar" );
+        ArtifactStub jarArtifact = new JarArtifactStub( getBasedir(), artifactHandler );
+        File jarFile = jarArtifact.getFile();
+
+        assertTrue( "jar not found: " + jarFile.toString(), jarFile.exists() );
+
+        // configure mojo
+        project.addArtifact( jarArtifact );
+        mojo.setOutputFileNameMapping( "@{artifactId}@.@{extension}@" );
+        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
+        mojo.execute();
+
+        // validate operation
+        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
+        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
+        // final name form is <artifactId>-<version>.<type>
+        File expectedJarArtifact = new File( webAppDirectory, "WEB-INF/lib/jarartifact.jar" );
+
+        assertTrue( "source files not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
+        assertTrue( "source files not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
+        assertTrue( "jar artifact not found: " + expectedJarArtifact.toString(), expectedJarArtifact.exists() );
+
+        // house keeping
+        expectedWebSourceFile.delete();
+        expectedWebSource2File.delete();
+        expectedJarArtifact.delete();
+    }
+
+    /**
+     * @throws Exception in case of an error.
+     */
+    public void testExplodedWarWithOutputFileNameMappingAndDuplicateDependencies()
+        throws Exception
+    {
+        // setup test data
+        String testId = "ExplodedWarWithFileNameMappingAndDuplicateDependencies";
+        MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
+        File webAppDirectory = new File( getTestDirectory(), testId );
+        File webAppSource = createWebAppSource( testId );
+        File classesDir = createClassesDir( testId, true );
+        EJBArtifactStub ejbArtifact = new EJBArtifactStub( getBasedir() );
+        EJBArtifactStub ejbArtifactDup = new EJBArtifactStub( getBasedir() );
+        File ejbFile = ejbArtifact.getFile();
+
+        // ejbArtifact has a hard coded file, only one assert is needed
+        assertTrue( "ejb not found: " + ejbFile.getAbsolutePath(), ejbFile.exists() );
+
+        // configure mojo
+        ejbArtifact.setGroupId( "org.sample.ejb" );
+        ejbArtifactDup.setGroupId( "org.dup.ejb" );
+        project.addArtifact( ejbArtifact );
+        project.addArtifact( ejbArtifactDup );
+        mojo.setOutputFileNameMapping( "@{artifactId}@.@{extension}@" );
+        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
+        mojo.execute();
+
+        // validate operation
+        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
+        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
+        // final name form is <artifactId>-<version>.<type>
+        File expectedEJBArtifact = new File( webAppDirectory, "WEB-INF/lib/org.sample.ejb-ejbartifact.jar" );
+        File expectedEJBDupArtifact = new File( webAppDirectory, "WEB-INF/lib/org.dup.ejb-ejbartifact.jar" );
+
+        assertTrue( "source files not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
+        assertTrue( "source files not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
+        assertTrue( "ejb artifact not found: " + expectedEJBArtifact.toString(), expectedEJBArtifact.exists() );
+        assertTrue( "ejb dup artifact not found: " + expectedEJBDupArtifact.toString(), expectedEJBDupArtifact.exists() );
+
+        // house keeping
+        expectedWebSourceFile.delete();
+        expectedWebSource2File.delete();
+        expectedEJBArtifact.delete();
+        expectedEJBDupArtifact.delete();
+    }
+
+    /* --------------------- 2.1 Overlay tests ----------------------------------- */
+
+    /*---------------------------*/
+
+}
diff --git a/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/WarInPlaceMojoTest.java b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/WarInPlaceMojoTest.java
new file mode 100644
index 000000000..d93433ccd
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/WarInPlaceMojoTest.java
@@ -0,0 +1,90 @@
+package org.apache.maven.plugins.war;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.plugins.war.stub.MavenProjectBasicStub;
+import org.apache.maven.plugins.war.stub.ResourceStub;
+
+import java.io.File;
+import java.util.LinkedList;
+
+public class WarInPlaceMojoTest
+    extends AbstractWarMojoTest
+{
+    protected static final String pomFilePath = getBasedir()
+        + "/target/test-classes/unit/warexplodedinplacemojo/plugin-config.xml";
+
+    protected File getTestDirectory()
+        throws Exception
+    {
+        return new File( getBasedir(), "target/test-classes/unit/warexplodedinplacemojo/test-dir" );
+    }
+
+    private WarInPlaceMojo mojo;
+
+    public void setUp()
+        throws Exception
+    {
+        super.setUp();
+
+        mojo = (WarInPlaceMojo) lookupMojo( "inplace", pomFilePath );
+        assertNotNull( mojo );
+    }
+
+    public void testEnvironment()
+        throws Exception
+    {
+        // see setUp
+    }
+
+    public void testSimpleExplodedInplaceWar()
+        throws Exception
+    {
+        // setup test data
+        String testId = "SimpleExplodedInplaceWar";
+        MavenProjectBasicStub project = new MavenProjectBasicStub();
+        File webAppSource = createWebAppSource( testId );
+        File classesDir = createClassesDir( testId, true );
+        File webAppResource = new File( getTestDirectory(), "resources" );
+        File sampleResource = new File( webAppResource, "pix/panis_na.jpg" );
+        ResourceStub[] resources = new ResourceStub[] { new ResourceStub() };
+
+        createFile( sampleResource );
+
+        // configure mojo
+        resources[0].setDirectory( webAppResource.getAbsolutePath() );
+        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, null, project );
+        setVariableValueToObject( mojo, "webResources", resources );
+        mojo.execute();
+
+        // validate operation
+        File expectedWebSourceFile = new File( webAppSource, "pansit.jsp" );
+        File expectedWebSource2File = new File( webAppSource, "org/web/app/last-exile.jsp" );
+        File expectedWebResourceFile = new File( webAppSource, "pix/panis_na.jpg" );
+        File expectedWEBINFDir = new File( webAppSource, "WEB-INF" );
+        File expectedMETAINFDir = new File( webAppSource, "META-INF" );
+
+        assertTrue( "source files not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
+        assertTrue( "source files not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
+        assertTrue( "resources doesn't exist: " + expectedWebResourceFile, expectedWebResourceFile.exists() );
+        assertTrue( "WEB-INF not found", expectedWEBINFDir.exists() );
+        assertTrue( "META-INF not found", expectedMETAINFDir.exists() );
+    }
+}
diff --git a/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/WarMojoTest.java b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/WarMojoTest.java
new file mode 100644
index 000000000..7a313ec25
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/WarMojoTest.java
@@ -0,0 +1,535 @@
+package org.apache.maven.plugins.war;
+
+/*
+ * 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.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.handler.ArtifactHandler;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugins.war.stub.JarArtifactStub;
+import org.apache.maven.plugins.war.stub.MavenProject4CopyConstructor;
+import org.apache.maven.plugins.war.stub.MavenProjectArtifactsStub;
+import org.apache.maven.plugins.war.stub.ProjectHelperStub;
+import org.apache.maven.plugins.war.stub.WarArtifact4CCStub;
+import org.codehaus.plexus.util.IOUtil;
+
+/**
+ * comprehensive test on buildExplodedWebApp is done on WarExplodedMojoTest
+ */
+public class WarMojoTest
+    extends AbstractWarMojoTest
+{
+    WarMojo mojo;
+
+    private static File pomFile = new File( getBasedir(),
+                                            "target/test-classes/unit/warmojotest/plugin-config-primary-artifact.xml" );
+
+    protected File getTestDirectory()
+    {
+        return new File( getBasedir(), "target/test-classes/unit/warmojotest" );
+    }
+
+    public void setUp()
+        throws Exception
+    {
+        super.setUp();
+        mojo = (WarMojo) lookupMojo( "war", pomFile );
+    }
+
+    public void testEnvironment()
+        throws Exception
+    {
+        // see setup
+    }
+
+    public void testSimpleWar()
+        throws Exception
+    {
+        String testId = "SimpleWar";
+        MavenProject4CopyConstructor project = new MavenProject4CopyConstructor();
+        String outputDir = getTestDirectory().getAbsolutePath() + "/" + testId + "-output";
+        File webAppDirectory = new File( getTestDirectory(), testId );
+        WarArtifact4CCStub warArtifact = new WarArtifact4CCStub( getBasedir() );
+        String warName = "simple";
+        File webAppSource = createWebAppSource( testId );
+        File classesDir = createClassesDir( testId, true );
+        File xmlSource = createXMLConfigDir( testId, new String[] { "web.xml" } );
+
+        project.setArtifact( warArtifact );
+        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
+        setVariableValueToObject( mojo, "outputDirectory", outputDir );
+        setVariableValueToObject( mojo, "warName", warName );
+        mojo.setWebXml( new File( xmlSource, "web.xml" ) );
+
+        mojo.execute();
+
+        // validate jar file
+        File expectedJarFile = new File( outputDir, "simple.war" );
+        assertJarContent( expectedJarFile, new String[] { "META-INF/MANIFEST.MF", "WEB-INF/web.xml", "pansit.jsp",
+            "org/web/app/last-exile.jsp", "META-INF/maven/org.apache.maven.plugin.test/maven-war-plugin-test/pom.xml",
+            "META-INF/maven/org.apache.maven.plugin.test/maven-war-plugin-test/pom.properties" }, new String[] { null,
+            mojo.getWebXml().toString(), null, null, null, null } );
+    }
+
+    public void testSimpleWarPackagingExcludeWithIncludesRegEx()
+        throws Exception
+    {
+        String testId = "SimpleWarPackagingExcludeWithIncludesRegEx";
+        MavenProject4CopyConstructor project = new MavenProject4CopyConstructor();
+        String outputDir = getTestDirectory().getAbsolutePath() + "/" + testId + "-output";
+        File webAppDirectory = new File( getTestDirectory(), testId );
+        WarArtifact4CCStub warArtifact = new WarArtifact4CCStub( getBasedir() );
+        String warName = "simple";
+        File webAppSource = createWebAppSource( testId );
+        File classesDir = createClassesDir( testId, true );
+        File xmlSource = createXMLConfigDir( testId, new String[] { "web.xml" } );
+
+        project.setArtifact( warArtifact );
+        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
+        setVariableValueToObject( mojo, "outputDirectory", outputDir );
+        setVariableValueToObject( mojo, "warName", warName );
+        mojo.setWebXml( new File( xmlSource, "web.xml" ) );
+        setVariableValueToObject( mojo, "packagingIncludes", "%regex[(.(?!exile))+]" );
+//        setVariableValueToObject( mojo, "packagingIncludes", "%regex" );
+
+        mojo.execute();
+
+        // validate jar file
+        File expectedJarFile = new File( outputDir, "simple.war" );
+        assertJarContent( expectedJarFile, new String[] { "META-INF/MANIFEST.MF", "WEB-INF/web.xml", "pansit.jsp",
+            "META-INF/maven/org.apache.maven.plugin.test/maven-war-plugin-test/pom.xml",
+            "META-INF/maven/org.apache.maven.plugin.test/maven-war-plugin-test/pom.properties" }, new String[] { null,
+            mojo.getWebXml().toString(), null, null, null, }, new String[] { "org/web/app/last-exile.jsp" } );
+    }
+
+    public void testClassifier()
+        throws Exception
+    {
+        String testId = "Classifier";
+        MavenProject4CopyConstructor project = new MavenProject4CopyConstructor();
+        String outputDir = getTestDirectory().getAbsolutePath() + "/" + testId + "-output";
+        File webAppDirectory = new File( getTestDirectory(), testId );
+        WarArtifact4CCStub warArtifact = new WarArtifact4CCStub( getBasedir() );
+        ProjectHelperStub projectHelper = new ProjectHelperStub();
+        String warName = "simple";
+        File webAppSource = createWebAppSource( testId );
+        File classesDir = createClassesDir( testId, true );
+        File xmlSource = createXMLConfigDir( testId, new String[] { "web.xml" } );
+
+        project.setArtifact( warArtifact );
+        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
+        setVariableValueToObject( mojo, "projectHelper", projectHelper );
+        setVariableValueToObject( mojo, "classifier", "test-classifier" );
+        setVariableValueToObject( mojo, "outputDirectory", outputDir );
+        setVariableValueToObject( mojo, "warName", warName );
+        mojo.setWebXml( new File( xmlSource, "web.xml" ) );
+
+        mojo.execute();
+
+        // validate jar file
+        File expectedJarFile = new File( outputDir, "simple-test-classifier.war" );
+        assertJarContent( expectedJarFile, new String[] { "META-INF/MANIFEST.MF", "WEB-INF/web.xml", "pansit.jsp",
+            "org/web/app/last-exile.jsp", "META-INF/maven/org.apache.maven.plugin.test/maven-war-plugin-test/pom.xml",
+            "META-INF/maven/org.apache.maven.plugin.test/maven-war-plugin-test/pom.properties" }, new String[] { null,
+            mojo.getWebXml().toString(), null, null, null, null } );
+    }
+
+    public void testPrimaryArtifact()
+        throws Exception
+    {
+        String testId = "PrimaryArtifact";
+        MavenProject4CopyConstructor project = new MavenProject4CopyConstructor();
+        String outputDir = getTestDirectory().getAbsolutePath() + "/" + testId + "-output";
+        File webAppDirectory = new File( getTestDirectory(), testId );
+        WarArtifact4CCStub warArtifact = new WarArtifact4CCStub( getBasedir() );
+        ProjectHelperStub projectHelper = new ProjectHelperStub();
+        String warName = "simple";
+        File webAppSource = createWebAppSource( testId );
+        File classesDir = createClassesDir( testId, true );
+        File xmlSource = createXMLConfigDir( testId, new String[] { "web.xml" } );
+
+        warArtifact.setFile( new File( "error.war" ) );
+        project.setArtifact( warArtifact );
+        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
+        setVariableValueToObject( mojo, "projectHelper", projectHelper );
+        setVariableValueToObject( mojo, "outputDirectory", outputDir );
+        setVariableValueToObject( mojo, "warName", warName );
+        mojo.setWebXml( new File( xmlSource, "web.xml" ) );
+
+        mojo.execute();
+
+        // validate jar file
+        File expectedJarFile = new File( outputDir, "simple.war" );
+        assertJarContent( expectedJarFile, new String[] { "META-INF/MANIFEST.MF", "WEB-INF/web.xml", "pansit.jsp",
+            "org/web/app/last-exile.jsp", "META-INF/maven/org.apache.maven.plugin.test/maven-war-plugin-test/pom.xml",
+            "META-INF/maven/org.apache.maven.plugin.test/maven-war-plugin-test/pom.properties" }, new String[] { null,
+            mojo.getWebXml().toString(), null, null, null, null } );
+    }
+
+    public void testNotPrimaryArtifact()
+        throws Exception
+    {
+        // use a different pom
+        File pom = new File( getBasedir(), "target/test-classes/unit/warmojotest/not-primary-artifact.xml" );
+        mojo = (WarMojo) lookupMojo( "war", pom );
+
+        String testId = "NotPrimaryArtifact";
+        MavenProject4CopyConstructor project = new MavenProject4CopyConstructor();
+        String outputDir = getTestDirectory().getAbsolutePath() + "/" + testId + "-output";
+        File webAppDirectory = new File( getTestDirectory(), testId );
+        WarArtifact4CCStub warArtifact = new WarArtifact4CCStub( getBasedir() );
+        ProjectHelperStub projectHelper = new ProjectHelperStub();
+        String warName = "simple";
+        File webAppSource = createWebAppSource( testId );
+        File classesDir = createClassesDir( testId, true );
+        File xmlSource = createXMLConfigDir( testId, new String[] { "web.xml" } );
+
+        warArtifact.setFile( new File( "error.war" ) );
+        project.setArtifact( warArtifact );
+        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
+        setVariableValueToObject( mojo, "projectHelper", projectHelper );
+        setVariableValueToObject( mojo, "outputDirectory", outputDir );
+        setVariableValueToObject( mojo, "warName", warName );
+        mojo.setWebXml( new File( xmlSource, "web.xml" ) );
+
+        mojo.execute();
+
+        // validate jar file
+        File expectedJarFile = new File( outputDir, "simple.war" );
+        assertJarContent( expectedJarFile, new String[] { "META-INF/MANIFEST.MF", "WEB-INF/web.xml", "pansit.jsp",
+            "org/web/app/last-exile.jsp", "META-INF/maven/org.apache.maven.plugin.test/maven-war-plugin-test/pom.xml",
+            "META-INF/maven/org.apache.maven.plugin.test/maven-war-plugin-test/pom.properties" }, new String[] { null,
+            mojo.getWebXml().toString(), null, null, null, null } );
+    }
+
+    public void testMetaInfContent()
+        throws Exception
+    {
+        String testId = "SimpleWarWithMetaInfContent";
+        MavenProject4CopyConstructor project = new MavenProject4CopyConstructor();
+        String outputDir = getTestDirectory().getAbsolutePath() + "/" + testId + "-output";
+        File webAppDirectory = new File( getTestDirectory(), testId );
+        WarArtifact4CCStub warArtifact = new WarArtifact4CCStub( getBasedir() );
+        String warName = "simple";
+        File webAppSource = createWebAppSource( testId );
+        File classesDir = createClassesDir( testId, true );
+        File xmlSource = createXMLConfigDir( testId, new String[] { "web.xml" } );
+
+        // Create the sample config.xml
+        final File configFile = new File( webAppSource, "META-INF/config.xml" );
+        createFile( configFile, "<config></config>" );
+
+        project.setArtifact( warArtifact );
+        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
+        setVariableValueToObject( mojo, "outputDirectory", outputDir );
+        setVariableValueToObject( mojo, "warName", warName );
+        mojo.setWebXml( new File( xmlSource, "web.xml" ) );
+
+        mojo.execute();
+
+        // validate jar file
+        File expectedJarFile = new File( outputDir, "simple.war" );
+        assertJarContent( expectedJarFile, new String[] { "META-INF/MANIFEST.MF", "META-INF/config.xml",
+            "WEB-INF/web.xml", "pansit.jsp", "org/web/app/last-exile.jsp",
+            "META-INF/maven/org.apache.maven.plugin.test/maven-war-plugin-test/pom.xml",
+            "META-INF/maven/org.apache.maven.plugin.test/maven-war-plugin-test/pom.properties" }, new String[] { null, null,
+            mojo.getWebXml().toString(), null, null, null, null } );
+    }
+
+    public void testMetaInfContentWithContainerConfig()
+        throws Exception
+    {
+        String testId = "SimpleWarWithContainerConfig";
+        MavenProject4CopyConstructor project = new MavenProject4CopyConstructor();
+        String outputDir = getTestDirectory().getAbsolutePath() + "/" + testId + "-output";
+        File webAppDirectory = new File( getTestDirectory(), testId );
+        WarArtifact4CCStub warArtifact = new WarArtifact4CCStub( getBasedir() );
+        String warName = "simple";
+        File webAppSource = createWebAppSource( testId );
+        File classesDir = createClassesDir( testId, true );
+        File xmlSource = createXMLConfigDir( testId, new String[] { "web.xml" } );
+
+        // Create the sample config.xml
+        final File configFile = new File( webAppSource, "META-INF/config.xml" );
+        createFile( configFile, "<config></config>" );
+
+        project.setArtifact( warArtifact );
+        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
+        setVariableValueToObject( mojo, "outputDirectory", outputDir );
+        setVariableValueToObject( mojo, "warName", warName );
+        mojo.setWebXml( new File( xmlSource, "web.xml" ) );
+        mojo.setContainerConfigXML( configFile );
+
+        mojo.execute();
+
+        // validate jar file
+        File expectedJarFile = new File( outputDir, "simple.war" );
+        assertJarContent( expectedJarFile, new String[] { "META-INF/MANIFEST.MF", "META-INF/config.xml",
+            "WEB-INF/web.xml", "pansit.jsp", "org/web/app/last-exile.jsp",
+            "META-INF/maven/org.apache.maven.plugin.test/maven-war-plugin-test/pom.xml",
+            "META-INF/maven/org.apache.maven.plugin.test/maven-war-plugin-test/pom.properties" }, new String[] { null, null,
+            mojo.getWebXml().toString(), null, null, null, null } );
+    }
+
+    public void testFailOnMissingWebXmlFalse()
+        throws Exception
+    {
+
+        String testId = "SimpleWarMissingWebXmlFalse";
+        MavenProject4CopyConstructor project = new MavenProject4CopyConstructor();
+        String outputDir = getTestDirectory().getAbsolutePath() + "/" + testId + "-output";
+        File webAppDirectory = new File( getTestDirectory(), testId );
+        WarArtifact4CCStub warArtifact = new WarArtifact4CCStub( getBasedir() );
+        String warName = "simple";
+        File webAppSource = createWebAppSource( testId );
+        File classesDir = createClassesDir( testId, true );
+
+        project.setArtifact( warArtifact );
+        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
+        setVariableValueToObject( mojo, "outputDirectory", outputDir );
+        setVariableValueToObject( mojo, "warName", warName );
+        mojo.setFailOnMissingWebXml( false );
+        mojo.execute();
+
+        // validate jar file
+        File expectedJarFile = new File( outputDir, "simple.war" );
+        final Map<String, JarEntry> jarContent =
+            assertJarContent( expectedJarFile, new String[] { "META-INF/MANIFEST.MF", "pansit.jsp",
+                "org/web/app/last-exile.jsp", "META-INF/maven/org.apache.maven.plugin.test/maven-war-plugin-test/pom.xml",
+                "META-INF/maven/org.apache.maven.plugin.test/maven-war-plugin-test/pom.properties" }, new String[] { null, null,
+                null, null, null } );
+
+        assertFalse( "web.xml should be missing", jarContent.containsKey( "WEB-INF/web.xml" ) );
+    }
+
+    public void testFailOnMissingWebXmlTrue()
+        throws Exception
+    {
+
+        String testId = "SimpleWarMissingWebXmlTrue";
+        MavenProject4CopyConstructor project = new MavenProject4CopyConstructor();
+        String outputDir = getTestDirectory().getAbsolutePath() + "/" + testId + "-output";
+        File webAppDirectory = new File( getTestDirectory(), testId );
+        WarArtifact4CCStub warArtifact = new WarArtifact4CCStub( getBasedir() );
+        String warName = "simple";
+        File webAppSource = createWebAppSource( testId );
+        File classesDir = createClassesDir( testId, true );
+
+        project.setArtifact( warArtifact );
+        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
+        setVariableValueToObject( mojo, "outputDirectory", outputDir );
+        setVariableValueToObject( mojo, "warName", warName );
+        mojo.setFailOnMissingWebXml( true );
+
+        try
+        {
+            mojo.execute();
+            fail( "Building of the war isn't possible because web.xml is missing" );
+        }
+        catch ( MojoExecutionException e )
+        {
+            // expected behaviour
+        }
+    }
+    
+    public void testFailOnMissingWebXmlNotSpecifiedAndServlet30Used()
+        throws Exception
+    {
+        String testId = "SimpleWarUnderServlet30";
+        MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
+        String outputDir = getTestDirectory().getAbsolutePath() + "/" + testId + "-output";
+        File webAppDirectory = new File( getTestDirectory(), testId );
+        WarArtifact4CCStub warArtifact = new WarArtifact4CCStub( getBasedir() );
+        String warName = "simple";
+        File webAppSource = createWebAppSource( testId );
+        File classesDir = createClassesDir( testId, true );
+
+        final ArtifactHandler artifactHandler = (ArtifactHandler) lookup( ArtifactHandler.ROLE, "jar" );
+        JarArtifactStub jarArtifactStub = new JarArtifactStub( getBasedir(), artifactHandler );
+        jarArtifactStub.setFile( new File( getBasedir(),
+                                           "/target/test-classes/unit/sample_wars/javax.servlet-api-3.0.1.jar" ) );
+        jarArtifactStub.setScope( Artifact.SCOPE_PROVIDED );
+        project.addArtifact( jarArtifactStub );
+
+        project.setArtifact( warArtifact );
+        project.setFile( warArtifact.getFile() );
+        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
+        setVariableValueToObject( mojo, "outputDirectory", outputDir );
+        setVariableValueToObject( mojo, "warName", warName );
+
+        mojo.execute();
+
+        // validate war file
+        File expectedWarFile = new File( outputDir, "simple.war" );
+        final Map<String, JarEntry> jarContent =
+            assertJarContent( expectedWarFile,
+                              new String[] { "META-INF/MANIFEST.MF", "pansit.jsp", "org/web/app/last-exile.jsp",
+                                  "META-INF/maven/org.apache.maven.plugin.test/maven-war-plugin-test/pom.xml",
+                                  "META-INF/maven/org.apache.maven.plugin.test/maven-war-plugin-test/pom.properties" },
+                              new String[] { null, null, null, null, null } );
+
+        assertFalse( "web.xml should be missing", jarContent.containsKey( "WEB-INF/web.xml" ) );
+    }
+
+    public void testFailOnMissingWebXmlNotSpecifiedAndServlet30NotUsed()
+        throws Exception
+    {
+        String testId = "SimpleWarNotUnderServlet30";
+        MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
+        String outputDir = getTestDirectory().getAbsolutePath() + "/" + testId + "-output";
+        File webAppDirectory = new File( getTestDirectory(), testId );
+        WarArtifact4CCStub warArtifact = new WarArtifact4CCStub( getBasedir() );
+        String warName = "simple";
+        File webAppSource = createWebAppSource( testId );
+        File classesDir = createClassesDir( testId, true );
+
+        project.setArtifact( warArtifact );
+        project.setFile( warArtifact.getFile() );
+        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
+        setVariableValueToObject( mojo, "outputDirectory", outputDir );
+        setVariableValueToObject( mojo, "warName", warName );
+
+        try
+        {
+            mojo.execute();
+            fail( "Building of the war isn't possible because no 'failOnMissingWebXml' policy was set and the project "
+                + "does not depend on Servlet 3.0" );
+        }
+        catch ( MojoExecutionException e )
+        {
+            // expected behaviour
+        }
+    }
+
+    public void testAttachClasses()
+        throws Exception
+    {
+        String testId = "AttachClasses";
+        MavenProject4CopyConstructor project = new MavenProject4CopyConstructor();
+        String outputDir = getTestDirectory().getAbsolutePath() + "/" + testId + "-output";
+        File webAppDirectory = new File( getTestDirectory(), testId );
+        WarArtifact4CCStub warArtifact = new WarArtifact4CCStub( getBasedir() );
+        String warName = "simple";
+        File webAppSource = createWebAppSource( testId );
+        File classesDir = createClassesDir( testId, false );
+        File xmlSource = createXMLConfigDir( testId, new String[] { "web.xml" } );
+
+        project.setArtifact( warArtifact );
+        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
+        setVariableValueToObject( mojo, "outputDirectory", outputDir );
+        setVariableValueToObject( mojo, "warName", warName );
+        mojo.setWebXml( new File( xmlSource, "web.xml" ) );
+        mojo.setAttachClasses( true );
+        mojo.setClassesClassifier( "classes" );
+
+        mojo.execute();
+
+        // validate jar file
+        File expectedJarFile = new File( outputDir, "simple-classes.jar" );
+        assertJarContent( expectedJarFile, new String[] { "META-INF/MANIFEST.MF", "sample-servlet.class" },
+                          new String[] { null, null } );
+    }
+
+    public void testAttachClassesWithCustomClassifier()
+        throws Exception
+    {
+        String testId = "AttachClassesCustomClassifier";
+        MavenProject4CopyConstructor project = new MavenProject4CopyConstructor();
+        String outputDir = getTestDirectory().getAbsolutePath() + "/" + testId + "-output";
+        File webAppDirectory = new File( getTestDirectory(), testId );
+        WarArtifact4CCStub warArtifact = new WarArtifact4CCStub( getBasedir() );
+        String warName = "simple";
+        File webAppSource = createWebAppSource( testId );
+        File classesDir = createClassesDir( testId, false );
+        File xmlSource = createXMLConfigDir( testId, new String[] { "web.xml" } );
+
+        project.setArtifact( warArtifact );
+        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
+        setVariableValueToObject( mojo, "outputDirectory", outputDir );
+        setVariableValueToObject( mojo, "warName", warName );
+        mojo.setWebXml( new File( xmlSource, "web.xml" ) );
+        mojo.setAttachClasses( true );
+        mojo.setClassesClassifier( "mystuff" );
+
+        mojo.execute();
+
+        // validate jar file
+        File expectedJarFile = new File( outputDir, "simple-mystuff.jar" );
+        assertJarContent( expectedJarFile, new String[] { "META-INF/MANIFEST.MF", "sample-servlet.class" },
+                          new String[] { null, null } );
+    }
+
+    protected Map<String, JarEntry> assertJarContent( final File expectedJarFile, final String[] files,
+                                                      final String[] filesContent )
+        throws IOException
+    {
+        return assertJarContent( expectedJarFile, files, filesContent, null );
+    }
+
+    protected Map<String, JarEntry> assertJarContent( final File expectedJarFile, final String[] files,
+                                                      final String[] filesContent, final String[] mustNotBeInJar )
+        throws IOException
+    {
+        // Sanity check
+        assertEquals( "Could not test, files and filesContent length does not match", files.length, filesContent.length );
+
+        assertTrue( "war file not created: " + expectedJarFile.toString(), expectedJarFile.exists() );
+        final Map<String, JarEntry> jarContent = new HashMap<>();
+        try ( JarFile jarFile = new JarFile( expectedJarFile ) ) {
+            Enumeration<JarEntry> enumeration = jarFile.entries();
+            while ( enumeration.hasMoreElements() )
+            {
+                JarEntry entry = enumeration.nextElement();
+                Object previousValue = jarContent.put( entry.getName(), entry );
+                assertNull( "Duplicate Entry in Jar File: " + entry.getName(), previousValue );
+            }
+    
+            for ( int i = 0; i < files.length; i++ )
+            {
+                String file = files[i];
+    
+                assertTrue( "File[" + file + "] not found in archive", jarContent.containsKey( file ) );
+                if ( filesContent[i] != null )
+                {
+                    assertEquals( "Content of file[" + file + "] does not match", filesContent[i],
+                                  IOUtil.toString( jarFile.getInputStream( jarContent.get( file ) ) ) );
+                }
+            }
+            if ( mustNotBeInJar != null )
+            {
+                for ( String file : mustNotBeInJar )
+                {
+                    assertFalse( "File[" + file + "]  found in archive", jarContent.containsKey( file ) );
+    
+                }
+            }
+            return jarContent;
+        }
+    }
+
+}
diff --git a/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/WarOverlaysTest.java b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/WarOverlaysTest.java
new file mode 100644
index 000000000..557357417
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/WarOverlaysTest.java
@@ -0,0 +1,494 @@
+package org.apache.maven.plugins.war;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.plugin.testing.stubs.ArtifactStub;
+import org.apache.maven.plugins.war.overlay.DefaultOverlay;
+import org.codehaus.plexus.util.FileUtils;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * @author Stephane Nicoll
+ */
+public class WarOverlaysTest
+    extends AbstractWarExplodedMojoTest
+{
+
+    private static File pomFile = new File( getBasedir(), "target/test-classes/unit/waroverlays/default.xml" );
+
+    public void setUp()
+        throws Exception
+    {
+        super.setUp();
+        generateFullOverlayWar( "overlay-full-1" );
+        generateFullOverlayWar( "overlay-full-2" );
+        generateFullOverlayWar( "overlay-full-3" );
+    }
+
+    protected File getPomFile()
+    {
+        return pomFile;
+    }
+
+    protected File getTestDirectory()
+    {
+        return new File( getBasedir(), "target/test-classes/unit/waroverlays" );
+    }
+
+    public void testEnvironment()
+        throws Exception
+    {
+        // see setup
+    }
+
+    public void testNoOverlay()
+        throws Exception
+    {
+        // setup test data
+        final String testId = "no-overlay";
+        final File xmlSource = createXMLConfigDir( testId, new String[] { "web.xml" } );
+
+        final File webAppDirectory = setUpMojo( testId, null );
+        try
+        {
+            mojo.setWebXml( new File( xmlSource, "web.xml" ) );
+            mojo.execute();
+
+            // Validate content of the webapp
+            assertDefaultContent( webAppDirectory );
+            assertWebXml( webAppDirectory );
+        }
+        finally
+        {
+            cleanDirectory( webAppDirectory );
+        }
+    }
+
+    public void testDefaultOverlay()
+        throws Exception
+    {
+        // setup test data
+        final String testId = "default-overlay";
+
+        // Add an overlay
+        final ArtifactStub overlay = buildWarOverlayStub( "overlay-one" );
+
+        final File webAppDirectory = setUpMojo( testId, new ArtifactStub[] { overlay } );
+        final List<File> assertedFiles = new ArrayList<>();
+        try
+        {
+            mojo.execute();
+            assertedFiles.addAll( assertDefaultContent( webAppDirectory ) );
+            assertedFiles.addAll( assertWebXml( webAppDirectory ) );
+            assertedFiles.addAll( assertCustomContent( webAppDirectory, new String[] { "index.jsp", "login.jsp" },
+                                                       "overlay file not found" ) );
+
+            // index and login come from overlay1
+            assertOverlayedFile( webAppDirectory, "overlay-one", "index.jsp" );
+            assertOverlayedFile( webAppDirectory, "overlay-one", "login.jsp" );
+
+            // Ok now check that there is no more files/directories
+            final FileFilter filter = new FileFilterImpl( webAppDirectory, new String[] { MANIFEST_PATH } );
+            assertWebAppContent( webAppDirectory, assertedFiles, filter );
+        }
+        finally
+        {
+            cleanDirectory( webAppDirectory );
+        }
+    }
+
+    public void testDefaultOverlays()
+        throws Exception
+    {
+        // setup test data
+        final String testId = "default-overlays";
+
+        // Add an overlay
+        final ArtifactStub overlay = buildWarOverlayStub( "overlay-one" );
+        final ArtifactStub overlay2 = buildWarOverlayStub( "overlay-two" );
+
+        final File webAppDirectory = setUpMojo( testId, new ArtifactStub[] { overlay, overlay2 } );
+        final List<File> assertedFiles = new ArrayList<>();
+        try
+        {
+            mojo.execute();
+            assertedFiles.addAll( assertDefaultContent( webAppDirectory ) );
+            assertedFiles.addAll( assertWebXml( webAppDirectory ) );
+            assertedFiles.addAll( assertCustomContent( webAppDirectory, new String[] { "index.jsp", "login.jsp",
+                "admin.jsp" }, "overlay file not found" ) );
+
+            // index and login come from overlay1
+            assertOverlayedFile( webAppDirectory, "overlay-one", "index.jsp" );
+            assertOverlayedFile( webAppDirectory, "overlay-one", "login.jsp" );
+
+            // admin comes from overlay2
+            // index and login comes from overlay1
+            assertOverlayedFile( webAppDirectory, "overlay-two", "admin.jsp" );
+
+            // Ok now check that there is no more files/directories
+            final FileFilter filter = new FileFilterImpl( webAppDirectory, new String[] { MANIFEST_PATH } );
+            assertWebAppContent( webAppDirectory, assertedFiles, filter );
+        }
+        finally
+        {
+            cleanDirectory( webAppDirectory );
+        }
+    }
+
+    /**
+     * Merge a dependent WAR when a file in the war source directory overrides one found in the WAR.
+     * 
+     * It also tests completeness of the resulting war as well as the proper order of dependencies.
+     *
+     * @throws Exception if any error occurs
+     */
+    public void testScenarioOneWithDefaulSettings()
+        throws Exception
+    {
+        // setup test data
+        final String testId = "scenario-one-default-settings";
+
+        // Add an overlay
+        final ArtifactStub overlay1 = buildWarOverlayStub( "overlay-full-1" );
+        final ArtifactStub overlay2 = buildWarOverlayStub( "overlay-full-2" );
+        final ArtifactStub overlay3 = buildWarOverlayStub( "overlay-full-3" );
+
+        final File webAppDirectory =
+            setUpMojo( testId, new ArtifactStub[] { overlay1, overlay2, overlay3 }, new String[] {
+                "org/sample/company/test.jsp", "jsp/b.jsp" } );
+
+        assertScenariOne( testId, webAppDirectory );
+    }
+
+    /**
+     * Tests that specifying the overlay explicitely has the same behavior as the default (i.e. order, etc).
+     * 
+     * The default project is not specified in this case so it is processed first by default
+     *
+     * @throws Exception if an error occurs
+     */
+    public void testScenarioOneWithOverlaySettings()
+        throws Exception
+    {
+        // setup test data
+        final String testId = "scenario-one-overlay-settings";
+
+        // Add an overlay
+        final ArtifactStub overlay1 = buildWarOverlayStub( "overlay-full-1" );
+        final ArtifactStub overlay2 = buildWarOverlayStub( "overlay-full-2" );
+        final ArtifactStub overlay3 = buildWarOverlayStub( "overlay-full-3" );
+
+        final File webAppDirectory =
+            setUpMojo( testId, new ArtifactStub[] { overlay1, overlay2, overlay3 }, new String[] {
+                "org/sample/company/test.jsp", "jsp/b.jsp" } );
+
+        // Add the tags
+        final List<Overlay> overlays = new ArrayList<>();
+        overlays.add( new DefaultOverlay( overlay1 ) );
+        overlays.add( new DefaultOverlay( overlay2 ) );
+        overlays.add( new DefaultOverlay( overlay3 ) );
+        mojo.setOverlays( overlays );
+
+        // current project ignored. Should be on top of the list
+        assertScenariOne( testId, webAppDirectory );
+    }
+
+    /**
+     * Tests that specifying the overlay explicitely has the same behavior as the default (i.e. order, etc).
+     * 
+     * The default project is explicitely specified so this should match the default.
+     *
+     * @throws Exception if an error occurs
+     */
+    public void testScenarioOneWithFullSettings()
+        throws Exception
+    {
+        // setup test data
+        final String testId = "scenario-one-full-settings";
+
+        // Add an overlay
+        final ArtifactStub overlay1 = buildWarOverlayStub( "overlay-full-1" );
+        final ArtifactStub overlay2 = buildWarOverlayStub( "overlay-full-2" );
+        final ArtifactStub overlay3 = buildWarOverlayStub( "overlay-full-3" );
+
+        final File webAppDirectory =
+            setUpMojo( testId, new ArtifactStub[] { overlay1, overlay2, overlay3 }, new String[] {
+                "org/sample/company/test.jsp", "jsp/b.jsp" } );
+
+        // Add the tags
+        final List<Overlay> overlays = new ArrayList<>();
+
+        // Add the default project explicitely
+        overlays.add( mojo.getCurrentProjectOverlay() );
+
+        // Other overlays
+        overlays.add( new DefaultOverlay( overlay1 ) );
+        overlays.add( new DefaultOverlay( overlay2 ) );
+        overlays.add( new DefaultOverlay( overlay3 ) );
+        mojo.setOverlays( overlays );
+
+        // current project ignored. Should be on top of the list
+        assertScenariOne( testId, webAppDirectory );
+    }
+
+    /**
+     * Runs the mojo and asserts a scenerio with 3 overlays and no includes/excludes settings.
+     *
+     * @param testId thie id of the test
+     * @param webAppDirectory the webapp directory
+     * @throws Exception if an exception occurs
+     */
+    private void assertScenariOne( String testId, File webAppDirectory )
+        throws Exception
+    {
+        final List<File> assertedFiles = new ArrayList<>();
+        try
+        {
+            mojo.execute();
+            assertedFiles.addAll( assertWebXml( webAppDirectory ) );
+            assertedFiles.addAll( assertCustomContent( webAppDirectory, new String[] { "jsp/a.jsp", "jsp/b.jsp",
+                "jsp/c.jsp", "jsp/d/a.jsp", "jsp/d/b.jsp", "jsp/d/c.jsp", "org/sample/company/test.jsp",
+                "WEB-INF/classes/a.class", "WEB-INF/classes/b.class", "WEB-INF/classes/c.class", "WEB-INF/lib/a.jar",
+                "WEB-INF/lib/b.jar", "WEB-INF/lib/c.jar" }, "overlay file not found" ) );
+
+            // Those files should come from the source webapp without any config
+            assertDefaultFileContent( testId, webAppDirectory, "jsp/b.jsp" );
+            assertDefaultFileContent( testId, webAppDirectory, "org/sample/company/test.jsp" );
+
+            // Everything else comes from overlay1 (order of addition in the dependencies)
+            assertOverlayedFile( webAppDirectory, "overlay-full-1", "jsp/a.jsp" );
+            assertOverlayedFile( webAppDirectory, "overlay-full-1", "jsp/c.jsp" );
+            assertOverlayedFile( webAppDirectory, "overlay-full-1", "jsp/d/a.jsp" );
+            assertOverlayedFile( webAppDirectory, "overlay-full-1", "jsp/d/b.jsp" );
+            assertOverlayedFile( webAppDirectory, "overlay-full-1", "jsp/d/c.jsp" );
+            assertOverlayedFile( webAppDirectory, "overlay-full-1", "WEB-INF/web.xml" );
+            assertOverlayedFile( webAppDirectory, "overlay-full-1", "WEB-INF/classes/a.class" );
+            assertOverlayedFile( webAppDirectory, "overlay-full-1", "WEB-INF/classes/b.class" );
+            assertOverlayedFile( webAppDirectory, "overlay-full-1", "WEB-INF/classes/c.class" );
+            assertOverlayedFile( webAppDirectory, "overlay-full-1", "WEB-INF/lib/a.jar" );
+            assertOverlayedFile( webAppDirectory, "overlay-full-1", "WEB-INF/lib/b.jar" );
+            assertOverlayedFile( webAppDirectory, "overlay-full-1", "WEB-INF/lib/c.jar" );
+
+            // Ok now check that there is no more files/directories
+            final FileFilter filter = new FileFilterImpl( webAppDirectory, new String[] { MANIFEST_PATH } );
+            assertWebAppContent( webAppDirectory, assertedFiles, filter );
+        }
+        finally
+        {
+            cleanDirectory( webAppDirectory );
+        }
+    }
+
+    public void testOverlaysIncludesExcludesWithMultipleDefinitions()
+        throws Exception
+    {
+        // setup test data
+        final String testId = "overlays-includes-excludes-multiple-defs";
+
+        // Add an overlay
+        final ArtifactStub overlay1 = buildWarOverlayStub( "overlay-full-1" );
+        final ArtifactStub overlay2 = buildWarOverlayStub( "overlay-full-2" );
+        final ArtifactStub overlay3 = buildWarOverlayStub( "overlay-full-3" );
+
+        final File webAppDirectory =
+            setUpMojo( testId, new ArtifactStub[] { overlay1, overlay2, overlay3 }, new String[] {
+                "org/sample/company/test.jsp", "jsp/b.jsp" } );
+
+        Overlay over1 = new DefaultOverlay( overlay3 );
+        over1.setExcludes( "**/a.*,**/c.*,**/*.xml" );
+
+        Overlay over2 = new DefaultOverlay( overlay1 );
+        over2.setIncludes( "jsp/d/*" );
+        over2.setExcludes( "jsp/d/a.jsp" );
+
+        Overlay over3 = new DefaultOverlay( overlay3 );
+        over3.setIncludes( "**/*.jsp" );
+
+        Overlay over4 = new DefaultOverlay( overlay2 );
+
+        mojo.setOverlays( new LinkedList<Overlay>() );
+        mojo.addOverlay( over1 );
+        mojo.addOverlay( over2 );
+        mojo.addOverlay( over3 );
+        mojo.addOverlay( mojo.getCurrentProjectOverlay() );
+        mojo.addOverlay( over4 );
+
+        final List<File> assertedFiles = new ArrayList<>();
+        try
+        {
+            mojo.execute();
+            assertedFiles.addAll( assertWebXml( webAppDirectory ) );
+            assertedFiles.addAll( assertCustomContent( webAppDirectory, new String[] { "jsp/a.jsp", "jsp/b.jsp",
+                "jsp/c.jsp", "jsp/d/a.jsp", "jsp/d/b.jsp", "jsp/d/c.jsp", "org/sample/company/test.jsp",
+                "WEB-INF/classes/a.class", "WEB-INF/classes/b.class", "WEB-INF/classes/c.class", "WEB-INF/lib/a.jar",
+                "WEB-INF/lib/b.jar", "WEB-INF/lib/c.jar" }, "overlay file not found" ) );
+
+            assertOverlayedFile( webAppDirectory, "overlay-full-3", "jsp/a.jsp" );
+            assertOverlayedFile( webAppDirectory, "overlay-full-3", "jsp/b.jsp" );
+            assertOverlayedFile( webAppDirectory, "overlay-full-3", "jsp/c.jsp" );
+            assertOverlayedFile( webAppDirectory, "overlay-full-3", "jsp/d/a.jsp" );
+            assertOverlayedFile( webAppDirectory, "overlay-full-3", "jsp/d/b.jsp" );
+            assertOverlayedFile( webAppDirectory, "overlay-full-1", "jsp/d/c.jsp" );
+            assertDefaultFileContent( testId, webAppDirectory, "org/sample/company/test.jsp" );
+            assertOverlayedFile( webAppDirectory, "overlay-full-2", "WEB-INF/web.xml" );
+            assertOverlayedFile( webAppDirectory, "overlay-full-2", "WEB-INF/classes/a.class" );
+            assertOverlayedFile( webAppDirectory, "overlay-full-3", "WEB-INF/classes/b.class" );
+            assertOverlayedFile( webAppDirectory, "overlay-full-2", "WEB-INF/classes/c.class" );
+            assertOverlayedFile( webAppDirectory, "overlay-full-2", "WEB-INF/lib/a.jar" );
+            assertOverlayedFile( webAppDirectory, "overlay-full-3", "WEB-INF/lib/b.jar" );
+            assertOverlayedFile( webAppDirectory, "overlay-full-2", "WEB-INF/lib/c.jar" );
+
+            // Ok now check that there is no more files/directories
+            final FileFilter filter = new FileFilterImpl( webAppDirectory, new String[] { MANIFEST_PATH } );
+            assertWebAppContent( webAppDirectory, assertedFiles, filter );
+        }
+        finally
+        {
+            cleanDirectory( webAppDirectory );
+        }
+    }
+
+    public void testOverlaysIncludesExcludesWithMultipleDefinitions2()
+        throws Exception
+    {
+        // setup test data
+        final String testId = "overlays-includes-excludes-multiple-defs2";
+
+        // Add an overlay
+        final ArtifactStub overlay1 = buildWarOverlayStub( "overlay-full-1" );
+        final ArtifactStub overlay2 = buildWarOverlayStub( "overlay-full-2" );
+        final ArtifactStub overlay3 = buildWarOverlayStub( "overlay-full-3" );
+
+        final File webAppDirectory =
+            setUpMojo( testId, new ArtifactStub[] { overlay1, overlay2, overlay3 }, new String[] {
+                "org/sample/company/test.jsp", "jsp/b.jsp" } );
+
+        Overlay over1 = new DefaultOverlay( overlay3 );
+        over1.setExcludes( "**/a.*,**/c.*,**/*.xml,jsp/b.jsp" );
+
+        Overlay over2 = new DefaultOverlay( overlay1 );
+        over2.setIncludes( "jsp/d/*" );
+        over2.setExcludes( "jsp/d/a.jsp" );
+
+        Overlay over3 = new DefaultOverlay( overlay3 );
+        over3.setIncludes( "**/*.jsp" );
+        over3.setExcludes( "jsp/b.jsp" );
+
+        Overlay over4 = new DefaultOverlay( overlay2 );
+
+        mojo.setOverlays( new LinkedList<Overlay>() );
+        mojo.addOverlay( over1 );
+        mojo.addOverlay( over2 );
+        mojo.addOverlay( over3 );
+        mojo.addOverlay( mojo.getCurrentProjectOverlay() );
+        mojo.addOverlay( over4 );
+
+        final List<File> assertedFiles = new ArrayList<>();
+        try
+        {
+            mojo.execute();
+            assertedFiles.addAll( assertWebXml( webAppDirectory ) );
+            assertedFiles.addAll( assertCustomContent( webAppDirectory, new String[] { "jsp/a.jsp", "jsp/b.jsp",
+                "jsp/c.jsp", "jsp/d/a.jsp", "jsp/d/b.jsp", "jsp/d/c.jsp", "org/sample/company/test.jsp",
+                "WEB-INF/classes/a.class", "WEB-INF/classes/b.class", "WEB-INF/classes/c.class", "WEB-INF/lib/a.jar",
+                "WEB-INF/lib/b.jar", "WEB-INF/lib/c.jar" }, "overlay file not found" ) );
+
+            assertOverlayedFile( webAppDirectory, "overlay-full-3", "jsp/a.jsp" );
+            assertDefaultFileContent( testId, webAppDirectory, "jsp/b.jsp" );
+            assertOverlayedFile( webAppDirectory, "overlay-full-3", "jsp/c.jsp" );
+            assertOverlayedFile( webAppDirectory, "overlay-full-3", "jsp/d/a.jsp" );
+            assertOverlayedFile( webAppDirectory, "overlay-full-3", "jsp/d/b.jsp" );
+            assertOverlayedFile( webAppDirectory, "overlay-full-1", "jsp/d/c.jsp" );
+            assertDefaultFileContent( testId, webAppDirectory, "org/sample/company/test.jsp" );
+            assertOverlayedFile( webAppDirectory, "overlay-full-2", "WEB-INF/web.xml" );
+            assertOverlayedFile( webAppDirectory, "overlay-full-2", "WEB-INF/classes/a.class" );
+            assertOverlayedFile( webAppDirectory, "overlay-full-3", "WEB-INF/classes/b.class" );
+            assertOverlayedFile( webAppDirectory, "overlay-full-2", "WEB-INF/classes/c.class" );
+            assertOverlayedFile( webAppDirectory, "overlay-full-2", "WEB-INF/lib/a.jar" );
+            assertOverlayedFile( webAppDirectory, "overlay-full-3", "WEB-INF/lib/b.jar" );
+            assertOverlayedFile( webAppDirectory, "overlay-full-2", "WEB-INF/lib/c.jar" );
+
+            // Ok now check that there is no more files/directories
+            final FileFilter filter = new FileFilterImpl( webAppDirectory, new String[] { MANIFEST_PATH } );
+            assertWebAppContent( webAppDirectory, assertedFiles, filter );
+        }
+        finally
+        {
+            cleanDirectory( webAppDirectory );
+        }
+
+    }
+
+    // Helpers
+
+    /**
+     * Asserts that the content of an overlayed file is correct.
+     * 
+     * Note that the <tt>filePath</tt> is relative to both the webapp directory and the overlayed directory, defined by
+     * the <tt>overlayId</tt>.
+     *
+     * @param webAppDirectory the webapp directory
+     * @param overlayId the id of the overlay
+     * @param filePath the relative path
+     * @throws IOException if an error occurred while reading the files
+     */
+    protected void assertOverlayedFile( File webAppDirectory, String overlayId, String filePath )
+        throws IOException
+    {
+        final File webAppFile = new File( webAppDirectory, filePath );
+        final File overlayFile = getOverlayFile( overlayId, filePath );
+        assertEquals( "Wrong content for overlayed file " + filePath, FileUtils.fileRead( overlayFile ),
+                      FileUtils.fileRead( webAppFile ) );
+
+    }
+
+    /**
+     * Asserts that the content of an overlayed file is correct.
+     * 
+     * Note that the <tt>filePath</tt> is relative to both the webapp directory and the overlayed directory, defined by
+     * the <tt>overlayId</tt>.
+     *
+     * @param testId te id of the test
+     * @param webAppDirectory the webapp directory
+     * @param filePath the relative path
+     * @throws IOException if an error occurred while reading the files
+     */
+    protected void assertDefaultFileContent( String testId, File webAppDirectory, String filePath )
+        throws Exception
+    {
+        final File webAppFile = new File( webAppDirectory, filePath );
+        final File sourceFile = new File( getWebAppSource( testId ), filePath );
+        final String expectedContent = sourceFile.toString();
+        assertEquals( "Wrong content for file " + filePath, expectedContent, FileUtils.fileRead( webAppFile ) );
+
+    }
+
+    protected ArtifactStub generateSimpleWarArtifactStub( String id )
+        throws Exception
+    {
+        return buildWarOverlayStub( id );
+    }
+}
\ No newline at end of file
diff --git a/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/WarZipTest.java b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/WarZipTest.java
new file mode 100644
index 000000000..88f665533
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/WarZipTest.java
@@ -0,0 +1,182 @@
+package org.apache.maven.plugins.war;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.handler.ArtifactHandler;
+import org.apache.maven.plugins.war.overlay.DefaultOverlay;
+import org.apache.maven.plugins.war.stub.MavenZipProject;
+import org.apache.maven.plugins.war.stub.WarArtifactStub;
+import org.apache.maven.plugins.war.stub.ZipArtifactStub;
+import org.codehaus.plexus.util.FileUtils;
+
+import java.io.File;
+import java.util.LinkedList;
+
+/**
+ * @author Olivier Lamy
+ * @since 7 Oct 07
+ */
+public class WarZipTest
+    extends AbstractWarMojoTest
+{
+    WarMojo mojo;
+
+    private static File pomFile = new File( getBasedir(), "src/test/resources/unit/warziptest/war-with-zip.xml" );
+
+    protected File getTestDirectory()
+    {
+        return new File( getBasedir(), "target/test-classes/unit/warziptest" );
+    }
+
+    public void setUp()
+        throws Exception
+    {
+        super.setUp();
+        mojo = (WarMojo) lookupMojo( "war", pomFile );
+    }
+
+    private Artifact buildZipArtifact()
+        throws Exception
+    {
+        ArtifactHandler artifactHandler = (ArtifactHandler) lookup( ArtifactHandler.ROLE, "jar" );
+        File zipFile = new File( getTestDirectory(), "foobar.zip" );
+        return new ZipArtifactStub( "src/test/resources/unit/warziptest", artifactHandler, zipFile );
+    }
+
+    private File configureMojo( String testId )
+        throws Exception
+    {
+        MavenZipProject project = new MavenZipProject();
+        String outputDir = getTestDirectory().getAbsolutePath() + File.separatorChar + testId + "-output";
+        // clean up
+        File outputDirFile = new File( outputDir );
+        if ( outputDirFile.exists() )
+        {
+            FileUtils.deleteDirectory( outputDirFile );
+        }
+        File webAppDirectory = new File( getTestDirectory(), testId );
+        WarArtifactStub warArtifact = new WarArtifactStub( getBasedir() );
+        String warName = "simple";
+        File webAppSource = createWebAppSource( testId );
+        File classesDir = createClassesDir( testId, true );
+        File xmlSource = createXMLConfigDir( testId, new String[] { "web.xml" } );
+        project.setArtifact( warArtifact );
+
+        this.configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
+        setVariableValueToObject( mojo, "outputDirectory", outputDir );
+        setVariableValueToObject( mojo, "warName", warName );
+        setVariableValueToObject( mojo, "workDirectory", new File( getTestDirectory(), "work" ) );
+        mojo.setWebXml( new File( xmlSource, "web.xml" ) );
+
+        project.getArtifacts().add( buildZipArtifact() );
+
+        return webAppDirectory;
+    }
+
+    public void testOneZipWithNoSkip()
+        throws Exception
+    {
+        File webAppDirectory = configureMojo( "one-zip" );
+
+        Overlay overlay = new DefaultOverlay( buildZipArtifact() );
+        // overlay.setSkip( false );
+        overlay.setType( "zip" );
+        mojo.addOverlay( overlay );
+        mojo.execute();
+
+        File foo = new File( webAppDirectory, "foo.txt" );
+        assertTrue( "foo.txt not exists", foo.exists() );
+        assertTrue( "foo.txt not a file", foo.isFile() );
+
+        File barDirectory = new File( webAppDirectory, "bar" );
+        assertTrue( "bar directory not exists", barDirectory.exists() );
+        assertTrue( "bar not a directory", barDirectory.isDirectory() );
+
+        File bar = new File( barDirectory, "bar.txt" );
+        assertTrue( "bar/bar.txt not exists", bar.exists() );
+        assertTrue( "bar/bar.txt not a file", bar.isFile() );
+    }
+
+    public void testOneZipWithTargetPathOverlay()
+        throws Exception
+    {
+        File webAppDirectory = configureMojo( "one-zip-overlay-targetPath" );
+
+        Overlay overlay = new DefaultOverlay( buildZipArtifact() );
+        overlay.setSkip( false );
+        overlay.setType( "zip" );
+        overlay.setTargetPath( "overridePath" );
+        mojo.addOverlay( overlay );
+
+        mojo.execute();
+
+        File foo = new File( webAppDirectory.getPath() + File.separatorChar + "overridePath", "foo.txt" );
+        assertTrue( "foo.txt not exists", foo.exists() );
+        assertTrue( "foo.txt not a file", foo.isFile() );
+
+        File barDirectory = new File( webAppDirectory.getPath() + File.separatorChar + "overridePath", "bar" );
+        assertTrue( "bar directory not exists", barDirectory.exists() );
+        assertTrue( "bar not a directory", barDirectory.isDirectory() );
+
+        File bar = new File( barDirectory, "bar.txt" );
+        assertTrue( "bar/bar.txt not exists", bar.exists() );
+        assertTrue( "bar/bar.txt not a file", bar.isFile() );
+    }
+
+    public void testOneZipDefaultSkip()
+        throws Exception
+    {
+        File webAppDirectory = configureMojo( "one-zip-overlay-skip" );
+
+        mojo.execute();
+
+        assertZipContentNotHere( webAppDirectory );
+    }
+
+    public void testOneZipWithForceSkip()
+        throws Exception
+    {
+        File webAppDirectory = configureMojo( "one-zip-overlay-skip" );
+        Overlay overlay = new DefaultOverlay( buildZipArtifact() );
+        overlay.setSkip( true );
+        overlay.setType( "zip" );
+        mojo.addOverlay( overlay );
+
+        mojo.execute();
+        assertZipContentNotHere( webAppDirectory );
+
+    }
+
+    protected void assertZipContentNotHere( File webAppDirectory )
+    {
+        File foo = new File( webAppDirectory.getPath() + File.separatorChar + "overridePath", "foo.txt" );
+        assertFalse( "foo.txt exists", foo.exists() );
+        assertFalse( "foo.txt a file", foo.isFile() );
+
+        File barDirectory = new File( webAppDirectory.getPath() + File.separatorChar + "overridePath", "bar" );
+        assertFalse( "bar directory exists", barDirectory.exists() );
+        assertFalse( "bar is a directory", barDirectory.isDirectory() );
+
+        File bar = new File( barDirectory, "bar.txt" );
+        assertFalse( "bar/bar.txt exists", bar.exists() );
+        assertFalse( "bar/bar.txt is a file", bar.isFile() );
+    }
+}
diff --git a/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/overlay/OverlayManagerTest.java b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/overlay/OverlayManagerTest.java
new file mode 100644
index 000000000..59ed9e0c7
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/overlay/OverlayManagerTest.java
@@ -0,0 +1,226 @@
+package org.apache.maven.plugins.war.overlay;
+
+/*
+ * 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.
+ */
+
+import static org.apache.maven.plugins.war.Overlay.DEFAULT_INCLUDES;
+import static org.apache.maven.plugins.war.Overlay.DEFAULT_EXCLUDES;
+
+import org.apache.maven.plugin.testing.stubs.ArtifactStub;
+import org.apache.maven.plugins.war.Overlay;
+import org.apache.maven.plugins.war.stub.MavenProjectArtifactsStub;
+import org.apache.maven.plugins.war.stub.WarArtifactStub;
+import org.codehaus.plexus.PlexusTestCase;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Stephane Nicoll
+ */
+public class OverlayManagerTest
+    extends PlexusTestCase
+{
+
+
+    public void testEmptyProject()
+        throws Exception
+    {
+        final MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
+        final List<Overlay> overlays = new ArrayList<>();
+        try
+        {
+            final Overlay currentProjectOverlay = Overlay.createInstance();
+            OverlayManager manager = new OverlayManager( overlays, project, DEFAULT_INCLUDES, DEFAULT_EXCLUDES,
+                                                         currentProjectOverlay );
+            assertNotNull( manager.getOverlays() );
+            assertEquals( 1, manager.getOverlays().size() );
+            assertEquals( currentProjectOverlay, manager.getOverlays().get( 0 ) );
+        }
+        catch ( InvalidOverlayConfigurationException e )
+        {
+            e.printStackTrace();
+            fail( "Should not have failed to validate a valid overly config " + e.getMessage() );
+        }
+    }
+
+    public void testAutodetectSimpleOverlay( Overlay currentProjectOverlay )
+        throws Exception
+    {
+
+        final MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
+        final ArtifactStub first = newWarArtifact( "test", "test-webapp" );
+        project.addArtifact( first );
+
+        final List<Overlay> overlays = new ArrayList<>();
+
+        try
+        {
+            final Overlay overlay = currentProjectOverlay;
+            OverlayManager manager = new OverlayManager( overlays, project, DEFAULT_INCLUDES, DEFAULT_EXCLUDES,
+                                                         overlay );
+            assertNotNull( manager.getOverlays() );
+            assertEquals( 2, manager.getOverlays().size() );
+            assertEquals( overlay, manager.getOverlays().get( 0 ) );
+            assertEquals( new DefaultOverlay( first ), manager.getOverlays().get( 1 ) );
+        }
+        catch ( InvalidOverlayConfigurationException e )
+        {
+            e.printStackTrace();
+            fail( "Should not have failed to validate a valid overlay config " + e.getMessage() );
+        }
+    }
+
+    public void testSimpleOverlay()
+        throws Exception
+    {
+
+        final MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
+        final ArtifactStub first = newWarArtifact( "test", "test-webapp" );
+        project.addArtifact( first );
+
+        final List<Overlay> overlays = new ArrayList<>();
+        overlays.add( new DefaultOverlay( first ) );
+
+        try
+        {
+            final Overlay currentProjectOverlay = Overlay.createInstance();
+            OverlayManager manager = new OverlayManager( overlays, project, DEFAULT_INCLUDES, DEFAULT_EXCLUDES,
+                                                         currentProjectOverlay );
+            assertNotNull( manager.getOverlays() );
+            assertEquals( 2, manager.getOverlays().size() );
+            assertEquals( Overlay.createInstance(), manager.getOverlays().get( 0 ) );
+            assertEquals( overlays.get( 0 ), manager.getOverlays().get( 1 ) );
+        }
+        catch ( InvalidOverlayConfigurationException e )
+        {
+            e.printStackTrace();
+            fail( "Should not have failed to validate a valid overlay config " + e.getMessage() );
+        }
+    }
+
+    public void testUnknownOverlay()
+        throws Exception
+    {
+
+        final MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
+        final ArtifactStub first = newWarArtifact( "test", "test-webapp" );
+        project.addArtifact( first );
+
+        final List<Overlay> overlays = new ArrayList<>();
+        overlays.add( new Overlay( "test", "test-webapp-2" ) );
+
+        try
+        {
+            final Overlay currentProjectOverlay = Overlay.createInstance();
+            new OverlayManager( overlays, project, DEFAULT_INCLUDES, DEFAULT_EXCLUDES, currentProjectOverlay );
+            fail( "Should have failed to validate an unknown overlay" );
+        }
+        catch ( InvalidOverlayConfigurationException e )
+        {
+            // OK
+        }
+    }
+
+    public void testCustomCurrentProject()
+        throws Exception
+    {
+
+        final MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
+        final ArtifactStub first = newWarArtifact( "test", "test-webapp" );
+        final ArtifactStub second = newWarArtifact( "test", "test-webapp-2" );
+        project.addArtifact( first );
+        project.addArtifact( second );
+
+        final List<Overlay> overlays = new ArrayList<>();
+        overlays.add( new DefaultOverlay( first ) );
+        final Overlay currentProjectOverlay = Overlay.createInstance();
+        overlays.add( currentProjectOverlay );
+
+        try
+        {
+            OverlayManager manager = new OverlayManager( overlays, project, DEFAULT_INCLUDES, DEFAULT_EXCLUDES,
+                                                         currentProjectOverlay );
+            assertNotNull( manager.getOverlays() );
+            assertEquals( 3, manager.getOverlays().size() );
+            assertEquals( overlays.get( 0 ), manager.getOverlays().get( 0 ) );
+            assertEquals( currentProjectOverlay, manager.getOverlays().get( 1 ) );
+            assertEquals( new DefaultOverlay( second ), manager.getOverlays().get( 2 ) );
+
+        }
+        catch ( InvalidOverlayConfigurationException e )
+        {
+            e.printStackTrace();
+            fail( "Should not have failed to validate a valid overlay config " + e.getMessage() );
+        }
+    }
+
+    public void testOverlaysWithSameArtifactAndGroupId()
+        throws Exception
+    {
+
+        final MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
+        final ArtifactStub first = newWarArtifact( "test", "test-webapp" );
+        final ArtifactStub second = newWarArtifact( "test", "test-webapp", "my-classifier" );
+
+        project.addArtifact( first );
+        project.addArtifact( second );
+
+        final List<Overlay> overlays = new ArrayList<>();
+        overlays.add( new DefaultOverlay( first ) );
+        overlays.add( new DefaultOverlay( second ) );
+
+        try
+        {
+            final Overlay currentProjectOverlay = Overlay.createInstance();
+            OverlayManager manager = new OverlayManager( overlays, project, DEFAULT_INCLUDES, DEFAULT_EXCLUDES,
+                                                         currentProjectOverlay );
+            assertNotNull( manager.getOverlays() );
+            assertEquals( 3, manager.getOverlays().size() );
+            assertEquals( currentProjectOverlay, manager.getOverlays().get( 0 ) );
+            assertEquals( overlays.get( 0 ), manager.getOverlays().get( 1 ) );
+            assertEquals( overlays.get( 1 ), manager.getOverlays().get( 2 ) );
+
+        }
+        catch ( InvalidOverlayConfigurationException e )
+        {
+            e.printStackTrace();
+            fail( "Should not have failed to validate a valid overlay config " + e.getMessage() );
+        }
+    }
+
+
+    protected ArtifactStub newWarArtifact( String groupId, String artifactId, String classifier )
+    {
+        final WarArtifactStub a = new WarArtifactStub( getBasedir() );
+        a.setGroupId( groupId );
+        a.setArtifactId( artifactId );
+        if ( classifier != null )
+        {
+            a.setClassifier( classifier );
+        }
+        return a;
+    }
+
+    protected ArtifactStub newWarArtifact( String groupId, String artifactId )
+    {
+        return newWarArtifact( groupId, artifactId, null );
+
+    }
+}
diff --git a/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/AarArtifactStub.java b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/AarArtifactStub.java
new file mode 100644
index 000000000..db5004964
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/AarArtifactStub.java
@@ -0,0 +1,79 @@
+package org.apache.maven.plugins.war.stub;
+
+/*
+ * 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.
+ */
+
+
+import org.apache.maven.artifact.handler.ArtifactHandler;
+
+import java.io.File;
+
+/**
+ * @author Stephane Nicoll
+ */
+public class AarArtifactStub
+    extends AbstractArtifactStub
+{
+    protected String groupId;
+
+    private ArtifactHandler artifactHandler;
+
+    public AarArtifactStub( String basedir, ArtifactHandler artifactHandler )
+    {
+        super( basedir );
+        this.artifactHandler = artifactHandler;
+    }
+
+    public void setGroupId( String id )
+    {
+        groupId = id;
+    }
+
+    public String getGroupId()
+    {
+        if ( groupId != null )
+        {
+            return groupId;
+        }
+        else
+        {
+            return "org.sample.aar";
+        }
+    }
+
+    public String getType()
+    {
+        return "aar";
+    }
+
+    public String getArtifactId()
+    {
+        return "aarartifact";
+    }
+
+    public File getFile()
+    {
+        return new File( basedir, "/target/test-classes/unit/sample_wars/simple.aar" );
+    }
+
+    public ArtifactHandler getArtifactHandler()
+    {
+        return artifactHandler;
+    }
+}
diff --git a/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/AbstractArtifactStub.java b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/AbstractArtifactStub.java
new file mode 100644
index 000000000..de6890ead
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/AbstractArtifactStub.java
@@ -0,0 +1,166 @@
+package org.apache.maven.plugins.war.stub;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.handler.ArtifactHandler;
+import org.apache.maven.artifact.handler.DefaultArtifactHandler;
+import org.apache.maven.artifact.versioning.VersionRange;
+import org.apache.maven.plugin.testing.stubs.ArtifactStub;
+
+public abstract class AbstractArtifactStub
+    extends ArtifactStub
+{
+    protected String basedir;
+
+    public AbstractArtifactStub( String _basedir )
+    {
+        basedir = _basedir;
+    }
+
+    public String getVersion()
+    {
+        return "0.0-Test";
+    }
+
+    @Override
+    public String getBaseVersion()
+    {
+        return getVersion();
+    }
+
+    public String getScope()
+    {
+        return Artifact.SCOPE_RUNTIME;
+    }
+
+    public VersionRange getVersionRange()
+    {
+        return VersionRange.createFromVersion( getVersion());
+    }
+
+    public boolean isOptional()
+    {
+        return false;
+    }
+
+    public ArtifactHandler getArtifactHandler()
+    {
+        return new DefaultArtifactHandler( getType() );
+    }
+
+    /*
+     * TODO: Copied from org/apache/maven/artifact/DefaultArtifact.java; Consider merging...
+     */
+    public int compareTo( Artifact a )
+    {
+        /* -- We need to support groupId=null (it is missing in DefaultArtifact.java) */
+        int result;
+        if ( a.getGroupId() != null )
+        {
+            result = getGroupId().compareTo( a.getGroupId() );
+        }
+        else
+        {
+            result = ( getGroupId() == null ? 0 : -1 );
+        }
+        /* -- */
+
+        if ( result == 0 )
+        {
+            result = getArtifactId().compareTo( a.getArtifactId() );
+            if ( result == 0 )
+            {
+                result = getType().compareTo( a.getType() );
+                if ( result == 0 )
+                {
+                    if ( getClassifier() == null )
+                    {
+                        if ( a.getClassifier() != null )
+                        {
+                            result = 1;
+                        }
+                    }
+                    else
+                    {
+                        if ( a.getClassifier() != null )
+                        {
+                            result = getClassifier().compareTo( a.getClassifier() );
+                        }
+                        else
+                        {
+                            result = -1;
+                        }
+                    }
+                    if ( result == 0 )
+                    {
+                        // We don't consider the version range in the comparison, just the resolved version
+                        result = getVersion().compareTo( a.getVersion() );
+                    }
+                }
+            }
+        }
+        return result;
+    }
+
+    /*
+     * TODO: Copied from org/apache/maven/artifact/DefaultArtifact.java; Consider merging...
+     */
+    public boolean equals( Object o )
+    {
+        if ( o == this )
+        {
+            return true;
+        }
+
+        if ( !( o instanceof Artifact ) )
+        {
+            return false;
+        }
+
+        Artifact a = (Artifact) o;
+
+        /* -- We need to support groupId=null (it is missing in DefaultArtifact.java) */
+        if ( a.getGroupId() == null ? ( getGroupId() != null ) : a.getGroupId().equals( getGroupId() ) )
+        {
+            return false;
+        }
+        else if ( !a.getArtifactId().equals( getArtifactId() ) )
+        {
+            return false;
+        }
+        else if ( !a.getVersion().equals( getVersion() ) )
+        {
+            return false;
+        }
+        else if ( !a.getType().equals( getType() ) )
+        {
+            return false;
+        }
+        else if ( a.getClassifier() == null ? getClassifier() != null : !a.getClassifier().equals( getClassifier() ) )
+        {
+            return false;
+        }
+
+        // We don't consider the version range in the comparison, just the resolved version
+
+        return true;
+    }
+}
diff --git a/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/EJBArtifactStub.java b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/EJBArtifactStub.java
new file mode 100644
index 000000000..7383715bd
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/EJBArtifactStub.java
@@ -0,0 +1,79 @@
+package org.apache.maven.plugins.war.stub;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.artifact.handler.ArtifactHandler;
+import org.apache.maven.artifact.handler.DefaultArtifactHandler;
+
+import java.io.File;
+
+public class EJBArtifactStub
+    extends AbstractArtifactStub
+{
+    protected String groupId;
+
+    public EJBArtifactStub( String _basedir )
+    {
+        super( _basedir );
+    }
+
+    public void setGroupId( String id )
+    {
+        groupId = id;
+    }
+
+    public String getGroupId()
+    {
+        if ( groupId != null )
+        {
+            return groupId;
+        }
+        else
+        {
+            return "org.sample.ejb";
+        }
+    }
+
+    public String getType()
+    {
+        return "ejb";
+    }
+
+    public String getArtifactId()
+    {
+        return "ejbartifact";
+    }
+
+    public File getFile()
+    {
+        return new File( basedir, "/target/test-classes/unit/sample_wars/ejb.jar" );
+    }
+
+    public ArtifactHandler getArtifactHandler()
+    {
+        return new DefaultArtifactHandler()
+        {
+            public String getExtension()
+            {
+                return "jar";
+            }
+        };
+    }
+}
diff --git a/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/EJBArtifactStubWithClassifier.java b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/EJBArtifactStubWithClassifier.java
new file mode 100644
index 000000000..35869c5e2
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/EJBArtifactStubWithClassifier.java
@@ -0,0 +1,90 @@
+package org.apache.maven.plugins.war.stub;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.artifact.handler.ArtifactHandler;
+import org.apache.maven.artifact.handler.DefaultArtifactHandler;
+
+import java.io.File;
+
+public class EJBArtifactStubWithClassifier
+    extends AbstractArtifactStub
+{
+    protected String groupId;
+    protected String classifier;
+
+    public EJBArtifactStubWithClassifier( String _basedir )
+    {
+        super( _basedir );
+    }
+
+    public void setGroupId( String id )
+    {
+        groupId = id;
+    }
+
+    public String getGroupId()
+    {
+        if ( groupId != null )
+        {
+            return groupId;
+        }
+        else
+        {
+            return "org.sample.ejb";
+        }
+    }
+
+    public String getType()
+    {
+        return "ejb";
+    }
+
+    public String getArtifactId()
+    {
+        return "ejbartifact";
+    }
+
+    public void setClassifier( String classifier )
+    {
+        this.classifier = classifier;
+    }
+
+    public String getClassifier()
+    {
+        return classifier;
+    }
+
+    public File getFile()
+    {
+        return new File( basedir, "/target/test-classes/unit/sample_wars/ejb.jar" );
+    }
+
+    public ArtifactHandler getArtifactHandler()
+    {
+        return new DefaultArtifactHandler()
+        {
+            public String getExtension()
+            {
+                return "jar";
+            }
+        };
+    }
+}
diff --git a/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/EJBClientArtifactStub.java b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/EJBClientArtifactStub.java
new file mode 100644
index 000000000..7e978967b
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/EJBClientArtifactStub.java
@@ -0,0 +1,84 @@
+package org.apache.maven.plugins.war.stub;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.artifact.handler.ArtifactHandler;
+import org.apache.maven.artifact.handler.DefaultArtifactHandler;
+
+import java.io.File;
+
+public class EJBClientArtifactStub
+    extends AbstractArtifactStub
+{
+    protected String groupId;
+
+    public EJBClientArtifactStub( String _basedir )
+    {
+        super( _basedir );
+    }
+
+    public void setGroupId( String id )
+    {
+        groupId = id;
+    }
+
+    public String getGroupId()
+    {
+        if ( groupId != null )
+        {
+            return groupId;
+        }
+        else
+        {
+            return "org.sample.ejb";
+        }
+    }
+
+    public String getType()
+    {
+        return "ejb-client";
+    }
+
+    public String getClassifier()
+    {
+        return "client";
+    }
+
+    public String getArtifactId()
+    {
+        return "ejbclientartifact";
+    }
+
+    public File getFile()
+    {
+        return new File( basedir, "/target/test-classes/unit/sample_wars/ejbclient.jar" );
+    }
+
+    public ArtifactHandler getArtifactHandler()
+    {
+        return new DefaultArtifactHandler()
+        {
+            public String getExtension()
+            {
+                return "jar";
+            }
+        };
+    }
+}
diff --git a/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/IncludeExcludeWarArtifactStub.java b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/IncludeExcludeWarArtifactStub.java
new file mode 100644
index 000000000..9f879b3c4
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/IncludeExcludeWarArtifactStub.java
@@ -0,0 +1,42 @@
+package org.apache.maven.plugins.war.stub;
+
+/*
+ * 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.
+ */
+
+import java.io.File;
+
+public class IncludeExcludeWarArtifactStub
+    extends WarArtifactStub
+{
+    public IncludeExcludeWarArtifactStub( String id )
+    {
+        super( id );
+        setGroupId( "wartests" );
+    }
+
+    public String getArtifactId()
+    {
+        return "war-include-exclude";
+    }
+
+    public File getFile()
+    {
+        return new File( basedir, "/target/test-classes/unit/sample_wars/include-exclude.war" );
+    }
+}
diff --git a/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/JarArtifactStub.java b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/JarArtifactStub.java
new file mode 100644
index 000000000..4b0899516
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/JarArtifactStub.java
@@ -0,0 +1,151 @@
+package org.apache.maven.plugins.war.stub;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.artifact.handler.ArtifactHandler;
+
+import java.io.File;
+
+public class JarArtifactStub
+    extends AbstractArtifactStub
+{
+
+    protected String groupId;
+
+    protected String artifactId;
+
+    protected String version;
+
+    protected boolean optional = false;
+
+    protected String scope;
+
+    private File file;
+
+    private ArtifactHandler artifactHandler;
+
+    public JarArtifactStub( String basedir, ArtifactHandler artifactHandler )
+    {
+        super( basedir );
+        this.artifactHandler = artifactHandler;
+    }
+
+    public void setGroupId( String id )
+    {
+        groupId = id;
+    }
+
+    public String getGroupId()
+    {
+        if ( groupId != null )
+        {
+            return groupId;
+        }
+        else
+        {
+            return "org.sample.jar";
+        }
+    }
+
+    public String getType()
+    {
+        return "jar";
+    }
+
+    public void setArtifactId( String artifactId )
+    {
+        this.artifactId = artifactId;
+    }
+
+    public String getArtifactId()
+    {
+        if ( artifactId != null )
+        {
+            return artifactId;
+        }
+        else
+        {
+            return "jarartifact";
+        }
+    }
+
+    public String getVersion()
+    {
+        if ( version != null )
+        {
+            return version;
+        }
+        else
+        {
+            return super.getVersion();
+        }
+    }
+
+    public void setVersion( String version )
+    {
+        this.version = version;
+    }
+
+    public boolean isOptional()
+    {
+        return optional;
+    }
+
+    public void setOptional( boolean optional )
+    {
+        this.optional = optional;
+    }
+
+    public String getScope()
+    {
+        if ( scope != null )
+        {
+            return scope;
+        }
+        else
+        {
+            return super.getScope();
+        }
+    }
+
+    public void setScope( String scope )
+    {
+        this.scope = scope;
+    }
+
+    public File getFile()
+    {
+        if ( file == null )
+        {
+            return new File( basedir, "/target/test-classes/unit/sample_wars/simple.jar" );
+        }
+        return file;
+    }
+
+    public void setFile( File file )
+    {
+        this.file = file;
+    }
+
+    public ArtifactHandler getArtifactHandler()
+    {
+        return artifactHandler;
+    }
+}
diff --git a/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/MarArtifactStub.java b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/MarArtifactStub.java
new file mode 100644
index 000000000..e26655749
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/MarArtifactStub.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.plugins.war.stub;
+
+import org.apache.maven.artifact.handler.ArtifactHandler;
+
+import java.io.File;
+
+/**
+ * @author Stephane Nicoll
+ */
+public class MarArtifactStub
+    extends AbstractArtifactStub
+{
+    protected String groupId;
+
+    private ArtifactHandler artifactHandler;
+
+    public MarArtifactStub( String basedir, ArtifactHandler artifactHandler )
+    {
+        super( basedir );
+        this.artifactHandler = artifactHandler;
+    }
+
+    public void setGroupId( String id )
+    {
+        groupId = id;
+    }
+
+    public String getGroupId()
+    {
+        if ( groupId != null )
+        {
+            return groupId;
+        }
+        else
+        {
+            return "org.sample.mar";
+        }
+    }
+
+    public String getType()
+    {
+        return "mar";
+    }
+
+    public String getArtifactId()
+    {
+        return "marartifact";
+    }
+
+    public File getFile()
+    {
+        return new File( basedir, "/target/test-classes/unit/sample_wars/simple.mar" );
+    }
+
+    public ArtifactHandler getArtifactHandler()
+    {
+        return artifactHandler;
+    }
+}
+
diff --git a/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/MavenProject4CopyConstructor.java b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/MavenProject4CopyConstructor.java
new file mode 100644
index 000000000..e9a58ab12
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/MavenProject4CopyConstructor.java
@@ -0,0 +1,64 @@
+package org.apache.maven.plugins.war.stub;
+
+/*
+ * 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.
+ */
+
+import java.io.File;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.model.Profile;
+import org.apache.maven.project.MavenProject;
+
+public class MavenProject4CopyConstructor
+    extends MavenProjectBasicStub
+{
+    protected ModelStub model;
+
+    public MavenProject4CopyConstructor()
+        throws Exception
+    {
+        initializeParentFields();
+    }
+
+    public List<Artifact> getAttachedArtifacts()
+    {
+        return new LinkedList<>();
+    }
+
+    // to prevent the MavenProject copy constructor from blowing up
+    private void initializeParentFields()
+    {
+        // the pom should be located in the isolated dummy root         
+        super.setFile( new File( getBasedir(), "pom.xml" ) );
+        super.setDependencyArtifacts( new HashSet<Artifact>() );
+        super.setArtifacts( new HashSet<Artifact>() );
+        super.setExtensionArtifacts( new HashSet<Artifact>() );
+        super.setRemoteArtifactRepositories( new LinkedList<ArtifactRepository>() );
+        super.setPluginArtifactRepositories( new LinkedList<ArtifactRepository>() );
+        super.setCollectedProjects( new LinkedList<MavenProject>() );
+        super.setActiveProfiles( new LinkedList<Profile>() );
+        super.setOriginalModel( null );
+        super.setExecutionProject( this );
+        super.setBuild( getBuild() );
+    }
+}
diff --git a/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/MavenProjectArtifactsStub.java b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/MavenProjectArtifactsStub.java
new file mode 100644
index 000000000..a8e21192c
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/MavenProjectArtifactsStub.java
@@ -0,0 +1,85 @@
+package org.apache.maven.plugins.war.stub;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.plugin.testing.stubs.ArtifactStub;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+public class MavenProjectArtifactsStub
+    extends MavenProjectBasicStub
+{
+    TreeSet<Artifact> artifacts;
+
+    public MavenProjectArtifactsStub()
+        throws Exception
+    {
+        artifacts = new TreeSet<>();
+    }
+
+    public void addArtifact( ArtifactStub stub )
+    {
+        artifacts.add( stub );
+    }
+
+    public Set<Artifact> getArtifacts()
+    {
+        return artifacts;
+    }
+
+    public List<Dependency> getDependencies()
+    {
+        if ( getArtifacts() == null )
+        {
+            return new ArrayList<>();
+        }
+        final List<Dependency> dependencies = new ArrayList<>();
+        for ( Artifact a : getArtifacts() )
+        {
+            Dependency dependency = new Dependency();
+            dependency.setArtifactId( a.getArtifactId() );
+            dependency.setGroupId( a.getGroupId() );
+            dependency.setVersion( a.getVersion() );
+            dependency.setScope( a.getScope() );
+            dependency.setType( a.getType() );
+            dependency.setClassifier( a.getClassifier() );
+            dependencies.add( dependency );
+
+        }
+        return dependencies;
+    }
+
+    public List<String> getRuntimeClasspathElements()
+    {
+        List<String> artifacts = new ArrayList<>();
+
+        artifacts.add(
+            "src/test/resources/unit/manifest/manifest-with-classpath/sample-artifacts/maven-artifact1-1.0-SNAPSHOT.jar" );
+        artifacts.add(
+            "src/test/resources/unit/manifest/manifest-with-classpath/sample-artifacts/maven-artifact2-1.0-SNAPSHOT.jar" );
+
+        return artifacts;
+    }
+}
diff --git a/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/MavenProjectBasicStub.java b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/MavenProjectBasicStub.java
new file mode 100644
index 000000000..7b2ac3007
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/MavenProjectBasicStub.java
@@ -0,0 +1,130 @@
+package org.apache.maven.plugins.war.stub;
+
+/*
+ * 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.
+ */
+
+import java.io.File;
+import java.util.HashSet;
+import java.util.Properties;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.model.Build;
+import org.apache.maven.model.Organization;
+import org.apache.maven.project.MavenProject;
+
+/**
+ * Stub
+ */
+public class MavenProjectBasicStub
+    extends MavenProject
+{
+    protected String testRootDir;
+
+    protected Properties properties;
+
+    public MavenProjectBasicStub()
+        throws Exception
+    {
+        super( new ModelStub() );
+        properties = new Properties();
+    }
+
+    public Set<Artifact> getArtifacts()
+    {
+        return new HashSet<>();
+    }
+
+    public String getName()
+    {
+        return "Test Project ";
+    }
+
+    public File getBasedir()
+    {
+        // create an isolated environment
+        // see setupTestEnvironment for details
+        //return new File( testRootDir );
+        return null;
+    }
+
+    public String getGroupId()
+    {
+        return "org.apache.maven.plugin.test";
+    }
+
+    public String getArtifactId()
+    {
+        return "maven-war-plugin-test";
+    }
+
+    public String getPackaging()
+    {
+        return "jar";
+    }
+
+    public String getVersion()
+    {
+        return "0.0-Test";
+    }
+
+    public void addProperty( String key, String value )
+    {
+        properties.put( key, value );
+    }
+
+    public Properties getProperties()
+    {
+        return properties;
+    }
+
+    public String getDescription()
+    {
+        return "Test Description";
+    }
+
+    public Organization getOrganization()
+    {
+        return new Organization()
+        {
+            public String getName()
+            {
+                return "Test Name";
+            }
+        };
+    }
+
+    @Override
+    public Build getBuild()
+    {
+        Build build = super.getBuild();
+
+        build.setDirectory( System.getProperty( "project.build.directory" ) );
+        build.setOutputDirectory( System.getProperty( "project.build.outputDirectory" ) );
+
+        return build;
+    }
+    
+    @Override
+    public MavenProject clone()
+    {
+        return this;
+    }
+
+}
diff --git a/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/MavenZipProject.java b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/MavenZipProject.java
new file mode 100644
index 000000000..c2ff17006
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/MavenZipProject.java
@@ -0,0 +1,58 @@
+package org.apache.maven.plugins.war.stub;
+
+/*
+ * 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.
+ */
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+
+/**
+ * @author Olivier Lamy
+ * @since 9 juin 07
+ */
+public class MavenZipProject
+    extends MavenProject4CopyConstructor
+{
+    private Set<Artifact> artifacts;
+
+    public MavenZipProject()
+        throws Exception
+    {
+        super();
+        this.artifacts = new HashSet<>();
+    }
+
+    public Set<Artifact> getArtifacts()
+    {
+        return this.artifacts;
+    }
+    
+    public Set<Artifact> getDependencyArtifacts()
+    {
+        return this.artifacts;
+    }
+
+    public void addArtifact( Artifact artifact )
+    {
+        this.artifacts.add( artifact );
+    }
+
+}
diff --git a/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/ModelStub.java b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/ModelStub.java
new file mode 100644
index 000000000..e15b8b2c9
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/ModelStub.java
@@ -0,0 +1,100 @@
+package org.apache.maven.plugins.war.stub;
+
+/*
+ * 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.
+ */
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Parent;
+import org.apache.maven.model.Profile;
+
+/**
+ * Stub
+ */
+public class ModelStub
+    extends Model
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 7802402157311376304L;
+
+    public ModelStub()
+    {
+
+    }
+
+    public String getVersion()
+    {
+        return "0.0-TEST";
+    }
+
+    public String getModelVersion()
+    {
+        return "0.0-TEST";
+    }
+
+    public String getName()
+    {
+        return "Test Model";
+    }
+
+    public String getGroupId()
+    {
+        return "org.apache.maven.test";
+    }
+
+    public String getPackaging()
+    {
+        return "jar";
+    }
+
+    public Parent getParent()
+    {
+        return new Parent();
+    }
+
+    public String getArtifactId()
+    {
+        return "maven-test-plugin";
+    }
+
+    public Properties getProperties()
+    {
+        return new Properties();
+    }
+
+    public List getPackages()
+    {
+        return new LinkedList();
+    }
+
+    public List<Profile> getProfiles()
+    {
+        return new LinkedList<>();
+    }
+
+    public List<String> getModules()
+    {
+        return new LinkedList<>();
+    }
+}
diff --git a/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/PARArtifactStub.java b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/PARArtifactStub.java
new file mode 100644
index 000000000..588b22e26
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/PARArtifactStub.java
@@ -0,0 +1,46 @@
+package org.apache.maven.plugins.war.stub;
+
+/*
+ * 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.
+ */
+
+import java.io.File;
+
+public class PARArtifactStub
+    extends AbstractArtifactStub
+{
+    public PARArtifactStub( String _basedir )
+    {
+        super( _basedir );
+    }
+
+    public String getType()
+    {
+        return "par";
+    }
+
+    public String getArtifactId()
+    {
+        return "parartifact";
+    }
+
+    public File getFile()
+    {
+        return new File( basedir, "/target/test-classes/unit/sample_wars/sample.par" );
+    }
+}
diff --git a/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/ProjectHelperStub.java b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/ProjectHelperStub.java
new file mode 100644
index 000000000..9fe114f99
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/ProjectHelperStub.java
@@ -0,0 +1,81 @@
+package org.apache.maven.plugins.war.stub;
+
+/*
+ * 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.
+ */
+
+import java.io.File;
+import java.util.List;
+
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.project.MavenProjectHelper;
+
+public class ProjectHelperStub
+    implements MavenProjectHelper
+{
+    File artifactFile;
+
+    String artifactType;
+
+    String artifactClassifier;
+
+    public File getArtifactFile()
+    {
+        return artifactFile;
+    }
+
+    public String getArtifactType()
+    {
+        return artifactType;
+    }
+
+    public String getArtifactClassifier()
+    {
+        return artifactClassifier;
+    }
+
+    public void attachArtifact( MavenProject project, File artifactFile, String artifactClassifier )
+    {
+
+    }
+
+    public void attachArtifact( MavenProject project, String artifactType, File artifactFile )
+    {
+
+    }
+
+    public void attachArtifact( MavenProject project, String _artifactType, String _artifactClassifier,
+                               File _artifactFile )
+    {
+        artifactType = _artifactType;
+        artifactClassifier = _artifactClassifier;
+        artifactFile = _artifactFile;
+    }
+
+    @SuppressWarnings( "rawtypes" )
+    public void addResource( MavenProject project, String resourceDirectory, List includes, List excludes )
+    {
+
+    }
+
+    @SuppressWarnings( "rawtypes" )
+    public void addTestResource( MavenProject project, String resourceDirectory, List includes, List excludes )
+    {
+
+    }
+}
diff --git a/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/ResourceStub.java b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/ResourceStub.java
new file mode 100644
index 000000000..dbe22b0b5
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/ResourceStub.java
@@ -0,0 +1,57 @@
+package org.apache.maven.plugins.war.stub;
+
+/*
+ * 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.
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.maven.model.Resource;
+
+public class ResourceStub
+    extends Resource
+{
+    /**
+     * 
+     */
+    private static final long serialVersionUID = 7685068931840967662L;
+
+    private String directory;
+
+    public List<String> getIncludes()
+    {
+        return new ArrayList<>();
+    }
+
+    public List<String> getExcludes()
+    {
+        return new ArrayList<>();
+    }
+
+    public void setDirectory( String _directory )
+    {
+        directory = _directory;
+    }
+
+    public String getDirectory()
+    {
+        return directory;
+    }
+
+}
diff --git a/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/TLDArtifactStub.java b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/TLDArtifactStub.java
new file mode 100644
index 000000000..bd2c2fd6d
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/TLDArtifactStub.java
@@ -0,0 +1,46 @@
+package org.apache.maven.plugins.war.stub;
+
+/*
+ * 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.
+ */
+
+import java.io.File;
+
+public class TLDArtifactStub
+    extends AbstractArtifactStub
+{
+    public TLDArtifactStub( String _basedir )
+    {
+        super( _basedir );
+    }
+
+    public String getType()
+    {
+        return "tld";
+    }
+
+    public String getArtifactId()
+    {
+        return "tldartifact";
+    }
+
+    public File getFile()
+    {
+        return new File( basedir, "/target/test-classes/unit/sample_wars/tld.jar" );
+    }
+}
diff --git a/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/WarArtifact4CCStub.java b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/WarArtifact4CCStub.java
new file mode 100644
index 000000000..c2b05b29e
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/WarArtifact4CCStub.java
@@ -0,0 +1,57 @@
+package org.apache.maven.plugins.war.stub;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.artifact.handler.ArtifactHandler;
+import org.apache.maven.artifact.handler.DefaultArtifactHandler;
+import org.apache.maven.artifact.versioning.VersionRange;
+
+/**
+ * stub for copy constructor
+ * to prevent the copy constructor from blowing up
+ */
+public class WarArtifact4CCStub
+    extends WarArtifactStub
+{
+    public WarArtifact4CCStub( String basedir )
+    {
+        super( basedir );
+    }
+
+    public VersionRange getVersionRange()
+    {
+        return VersionRange.createFromVersion( getVersion() );
+    }
+
+    public String getGroupId()
+    {
+        return "org.maven.plugin.test";
+    }
+
+    public String getClassifier()
+    {
+        return "testclassifier";
+    }
+
+    public ArtifactHandler getArtifactHandler()
+    {
+        return new DefaultArtifactHandler();
+    }
+}
diff --git a/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/WarArtifactStub.java b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/WarArtifactStub.java
new file mode 100644
index 000000000..9b4c63ead
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/WarArtifactStub.java
@@ -0,0 +1,115 @@
+package org.apache.maven.plugins.war.stub;
+
+/*
+ * 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.
+ */
+
+import java.io.File;
+
+/**
+ * Stub
+ */
+public class WarArtifactStub
+    extends AbstractArtifactStub
+{
+
+    private String groupId;
+
+    private String artifactId;
+
+    private String classifier;
+
+    private File file;
+
+    public WarArtifactStub( String _basedir )
+    {
+        super( _basedir );
+    }
+
+    public String getType()
+    {
+        return "war";
+    }
+
+    public String getArtifactId()
+    {
+        if ( artifactId == null )
+        {
+            return "simple";
+        }
+        else
+        {
+            return artifactId;
+        }
+    }
+
+    public void setArtifactId( String _artifactId )
+    {
+        artifactId = _artifactId;
+    }
+
+
+    public String getGroupId()
+    {
+        if ( groupId == null )
+        {
+            return "wartests";
+        }
+        else
+        {
+            return groupId;
+        }
+    }
+
+    public void setGroupId( String groupId )
+    {
+        this.groupId = groupId;
+    }
+
+    public File getFile()
+    {
+        if ( file == null )
+        {
+            return new File( basedir, "/target/test-classes/unit/sample_wars/simple.war" );
+        }
+        else
+        {
+            return file;
+        }
+    }
+
+    public void setFile( File _file )
+    {
+        file = _file;
+    }
+
+    public String getClassifier()
+    {
+        return classifier;
+    }
+
+    public void setClassifier( String classifier )
+    {
+        this.classifier = classifier;
+    }
+
+    public boolean hasClassifier()
+    {
+        return classifier != null;
+    }
+}
diff --git a/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/WarOverlayStub.java b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/WarOverlayStub.java
new file mode 100644
index 000000000..892f9791e
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/WarOverlayStub.java
@@ -0,0 +1,76 @@
+package org.apache.maven.plugins.war.stub;
+
+/*
+ * 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.
+ */
+
+import java.io.File;
+
+/**
+ * @author Stephane Nicoll
+ */
+public class WarOverlayStub
+    extends AbstractArtifactStub
+{
+
+
+    private final String artifactId;
+
+    private File file;
+
+    public WarOverlayStub( String _basedir, String artifactId, File warFile )
+    {
+        super( _basedir );
+        if ( artifactId == null )
+        {
+            throw new NullPointerException( "Id could not be null." );
+        }
+        if ( warFile == null )
+        {
+            throw new NullPointerException( "warFile could not be null." );
+
+        }
+        else if ( !warFile.exists() )
+        {
+            throw new IllegalStateException( "warFile[" + file.getAbsolutePath() + "] should exist." );
+        }
+        this.artifactId = artifactId;
+        this.file = warFile;
+    }
+
+    public String getType()
+    {
+        return "war";
+    }
+
+    public String getArtifactId()
+    {
+        return artifactId;
+    }
+
+    public String getGroupId()
+    {
+        return "wartests";
+    }
+
+    public File getFile()
+    {
+        return file;
+    }
+
+}
diff --git a/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/XarArtifactStub.java b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/XarArtifactStub.java
new file mode 100644
index 000000000..92e195f28
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/XarArtifactStub.java
@@ -0,0 +1,79 @@
+package org.apache.maven.plugins.war.stub;
+
+/*
+ * 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.
+ */
+
+
+import org.apache.maven.artifact.handler.ArtifactHandler;
+
+import java.io.File;
+
+/**
+ * @author Auke Schrijnen
+ */
+public class XarArtifactStub
+    extends AbstractArtifactStub
+{
+    protected String groupId;
+
+    private ArtifactHandler artifactHandler;
+
+    public XarArtifactStub( String basedir, ArtifactHandler artifactHandler )
+    {
+        super( basedir );
+        this.artifactHandler = artifactHandler;
+    }
+
+    public void setGroupId( String id )
+    {
+        groupId = id;
+    }
+
+    public String getGroupId()
+    {
+        if ( groupId != null )
+        {
+            return groupId;
+        }
+        else
+        {
+            return "org.sample.xar";
+        }
+    }
+
+    public String getType()
+    {
+        return "xar";
+    }
+
+    public String getArtifactId()
+    {
+        return "xarartifact";
+    }
+
+    public File getFile()
+    {
+        return new File( basedir, "/target/test-classes/unit/sample_wars/simple.xar" );
+    }
+
+    public ArtifactHandler getArtifactHandler()
+    {
+        return artifactHandler;
+    }
+}
diff --git a/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/ZipArtifactStub.java b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/ZipArtifactStub.java
new file mode 100644
index 000000000..50c01d98a
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/stub/ZipArtifactStub.java
@@ -0,0 +1,89 @@
+package org.apache.maven.plugins.war.stub;
+
+/*
+ * 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.
+ */
+
+import java.io.File;
+
+import org.apache.maven.artifact.handler.ArtifactHandler;
+
+/**
+ * @author Olivier Lamy
+ * @since 8 juin 07
+ */
+public class ZipArtifactStub
+    extends AbstractArtifactStub
+{
+    private File zip;
+
+    public ZipArtifactStub( String basedir, ArtifactHandler artifactHandler, File zipFile )
+    {
+        super( basedir );
+        super.setArtifactHandler( artifactHandler );
+        this.zip = zipFile;
+    }
+
+    
+    public String getId()
+    {
+        return null;
+    }
+
+    public ArtifactHandler getArtifactHandler()
+    {
+        return super.getArtifactHandler();
+    }
+
+    public String getScope()
+    {
+        return super.getScope();
+    }
+
+    public String getVersion()
+    {
+        return "1.0";
+    }
+
+    public boolean isOptional()
+    {
+        return super.isOptional();
+    }
+
+    public File getFile()
+    {
+        return this.zip;
+    }
+
+    public String getType()
+    {
+        return "zip";
+    }
+
+   
+    public String getArtifactId()
+    {
+        return "zipId";
+    }
+
+    public String getGroupId()
+    {
+        return "zipGroupId";
+    }
+
+}
diff --git a/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/util/PathSetTest.java b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/util/PathSetTest.java
new file mode 100644
index 000000000..6375109ef
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/util/PathSetTest.java
@@ -0,0 +1,257 @@
+package org.apache.maven.plugins.war.util;
+
+/*
+ * 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.
+ */
+
+import junit.framework.TestCase;
+
+import org.apache.maven.plugins.war.util.PathSet;
+import org.codehaus.plexus.util.StringUtils;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+public class PathSetTest
+    extends TestCase
+{
+
+    /* --------------- Normalization tests --------------*/
+
+    /**
+     * Test method for 'org.apache.maven.plugin.war.PathSet.normalizeSubPath(String)'
+     */
+    public void testNormalizeSubPath()
+    {
+        assertEquals( "Normalized path error", "", PathSet.normalizeSubPath( "" ) );
+        assertEquals( "Normalized path error", "", PathSet.normalizeSubPath( "/" ) );
+        assertEquals( "Normalized path error", "", PathSet.normalizeSubPath( "////" ) );
+        assertEquals( "Normalized path error", "", PathSet.normalizeSubPath( "\\" ) );
+        assertEquals( "Normalized path error", "", PathSet.normalizeSubPath( "\\\\\\\\" ) );
+
+        assertEquals( "Normalized path error", "abc", PathSet.normalizeSubPath( "abc" ) );
+        assertEquals( "Normalized path error", "abc", PathSet.normalizeSubPath( "/abc" ) );
+        assertEquals( "Normalized path error", "abc", PathSet.normalizeSubPath( "////abc" ) );
+        assertEquals( "Normalized path error", "abc", PathSet.normalizeSubPath( "\\abc" ) );
+        assertEquals( "Normalized path error", "abc", PathSet.normalizeSubPath( "\\\\\\\\abc" ) );
+
+        assertEquals( "Normalized path error", "abc/def/xyz", PathSet.normalizeSubPath( "abc/def\\xyz\\" ) );
+        assertEquals( "Normalized path error", "abc/def/xyz", PathSet.normalizeSubPath( "/abc/def/xyz/" ) );
+        assertEquals( "Normalized path error", "abc/def/xyz", PathSet.normalizeSubPath( "////abc/def/xyz/" ) );
+        assertEquals( "Normalized path error", "abc/def/xyz", PathSet.normalizeSubPath( "\\abc/def/xyz/" ) );
+        assertEquals( "Normalized path error", "abc/def/xyz",
+                PathSet.normalizeSubPath( "\\\\\\\\abc/def/xyz/" ) );
+        // MWAR-371
+        assertEquals( "Normalized path error", "abc/def/ghi",
+                PathSet.normalizeSubPath( "///abc/////def////ghi//" ) );
+    }
+
+    /* -------------- Operations tests ------------------*/
+
+    /**
+     * Test method for:
+     * <ul>
+     * <li>org.apache.maven.plugin.war.PathSet.PathSet()</li>
+     * <li>org.apache.maven.plugin.war.PathSet.size()</li>
+     * <li>org.apache.maven.plugin.war.PathSet.add()</li>
+     * <li>org.apache.maven.plugin.war.PathSet.addAll()</li>
+     * <li>org.apache.maven.plugin.war.PathSet.iterate()</li>
+     * <li>org.apache.maven.plugin.war.PathSet.contains()</li>
+     * <li>org.apache.maven.plugin.war.PathSet.addPrefix(String)</li>
+     * </ul>
+     */
+    public void testPathsSetBasic()
+    {
+        PathSet ps = new PathSet();
+        assertEquals( "Unexpected PathSet size", ps.size(), 0 );
+        Iterator<String> iter = ps.iterator();
+        assertNotNull( "Iterator is null", iter );
+        assertFalse( "Can iterate on empty set", iter.hasNext() );
+
+        ps.add( "abc" );
+        assertEquals( "Unexpected PathSet size", ps.size(), 1 );
+        ps.add( "abc" );
+        assertEquals( "Unexpected PathSet size", ps.size(), 1 );
+        ps.add( "xyz/abc" );
+        assertEquals( "Unexpected PathSet size", ps.size(), 2 );
+        ps.add( "///abc" );
+        assertEquals( "Unexpected PathSet size", ps.size(), 2 );
+        ps.add( "///xyz\\abc" );
+        assertEquals( "Unexpected PathSet size", ps.size(), 2 );
+
+        ps.addAll( ps );
+        assertEquals( "Unexpected PathSet size", ps.size(), 2 );
+
+        int i = 0;
+        for (String pathstr : ps) {
+            i++;
+            assertTrue(ps.contains(pathstr));
+            assertTrue(ps.contains("/" + pathstr));
+            assertTrue(ps.contains("/" + StringUtils.replace(pathstr, '/', '\\')));
+            assertFalse(ps.contains("/" + StringUtils.replace(pathstr, '/', '\\') + "/a"));
+            assertFalse(ps.contains("/a/" + StringUtils.replace(pathstr, '/', '\\')));
+        }
+        assertEquals( "Wrong count of iterations", 2, i );
+
+        ps.addPrefix( "/ab/c/" );
+        i = 0;
+        for (String pathstr : ps) {
+            i++;
+            assertTrue(pathstr.startsWith("ab/c/"));
+            assertFalse(pathstr.startsWith("ab/c//"));
+            assertTrue(ps.contains(pathstr));
+            assertTrue(ps.contains("/" + pathstr));
+            assertTrue(ps.contains("/" + StringUtils.replace(pathstr, '/', '\\')));
+            assertFalse(ps.contains("/" + StringUtils.replace(pathstr, '/', '\\') + "/a"));
+            assertFalse(ps.contains("/ab/" + StringUtils.replace(pathstr, '/', '\\')));
+        }
+        assertEquals( "Wrong count of iterations", 2, i );
+    }
+
+    /**
+     * Test method for:
+     * <ul>
+     * <li>org.apache.maven.plugin.war.PathSet.PathSet(Collection)</li>
+     * <li>org.apache.maven.plugin.war.PathSet.PathSet(String[])</li>
+     * <li>org.apache.maven.plugin.war.PathSet.Add</li>
+     * <li>org.apache.maven.plugin.war.PathSet.AddAll(String[],String)</li>
+     * <li>org.apache.maven.plugin.war.PathSet.AddAll(Collection,String)</li>
+     * </ul>
+     */
+    public void testPathsSetAddAlls()
+    {
+        Set<String> s1set = new HashSet<>();
+        s1set.add( "/a/b" );
+        s1set.add( "a/b/c" );
+        s1set.add( "a\\b/c" );
+        s1set.add( "//1//2\3a" );
+
+        String[] s2ar = new String[]{"/a/b", "a2/b2/c2", "a2\\b2/c2", "//21//22\23a"};
+
+        PathSet ps1 = new PathSet( s1set );
+        assertEquals( "Unexpected PathSet size", 3, ps1.size() );
+
+        PathSet ps2 = new PathSet( s2ar );
+        assertEquals( "Unexpected PathSet size", 3, ps2.size() );
+
+        ps1.addAll( s2ar );
+        assertEquals( "Unexpected PathSet size", 5, ps1.size() );
+
+        ps2.addAll( s1set );
+        assertEquals( "Unexpected PathSet size", 5, ps2.size() );
+
+        for (String str : ps1) {
+            assertTrue(str, ps2.contains(str));
+            assertTrue(ps2.contains("/" + str));
+            assertTrue(ps1.contains(str));
+            assertTrue(ps1.contains("/" + str));
+        }
+
+        for (String str : ps2) {
+            assertTrue(ps1.contains(str));
+            assertTrue(ps1.contains("/" + str));
+            assertTrue(ps2.contains(str));
+            assertTrue(ps2.contains("/" + str));
+        }
+
+        ps1.addAll( s2ar, "/pref/" );
+        assertEquals( "Unexpected PathSet size", 8, ps1.size() );
+
+        ps2.addAll( s2ar, "/pref/" );
+        assertEquals( "Unexpected PathSet size", 8, ps2.size() );
+
+        for (String str : ps1) {
+            assertTrue(str, ps2.contains(str));
+            assertTrue(ps2.contains("/" + str));
+            assertTrue(ps1.contains(str));
+            assertTrue(ps1.contains("/" + str));
+        }
+
+        for (String str : ps2) {
+            assertTrue(ps1.contains(str));
+            assertTrue(ps1.contains("/" + str));
+            assertTrue(ps2.contains(str));
+            assertTrue(ps2.contains("/" + str));
+        }
+
+        PathSet ps3 = new PathSet();
+        ps3.addAll(new String[]{ "a/b/c" }, "d");
+        assertTrue( "Unexpected PathSet path", ps3.contains( "d/a/b/c" ) );
+    }
+
+    /**
+     * Test method for 'org.apache.maven.plugin.war.PathSet.addAllFilesInDirectory(File, String)'
+     *
+     * @throws IOException if an io error occurred
+     */
+    public void testAddAllFilesInDirectory()
+        throws IOException
+    {
+        PathSet ps = new PathSet();
+
+        /* Preparing directory structure*/
+        File testDir = new File( "target/testAddAllFilesInDirectory" );
+        testDir.mkdirs();
+
+        File f1 = new File( testDir, "f1" );
+        f1.createNewFile();
+        File f2 = new File( testDir, "f2" );
+        f2.createNewFile();
+
+        File d1 = new File( testDir, "d1" );
+        File d1d2 = new File( testDir, "d1/d2" );
+        d1d2.mkdirs();
+        File d1d2f1 = new File( d1d2, "f1" );
+        d1d2f1.createNewFile();
+        File d1d2f2 = new File( d1d2, "f2" );
+        d1d2f2.createNewFile();
+
+        ps.addAllFilesInDirectory( new File( "target/testAddAllFilesInDirectory" ), "123/" );
+        assertEquals( "Unexpected PathSet size", 4, ps.size() );
+
+        /*No changes after adding duplicates*/
+        ps.addAllFilesInDirectory( new File( "target/testAddAllFilesInDirectory" ), "123/" );
+        assertEquals( "Unexpected PathSet size", 4, ps.size() );
+
+        /*Cleanup*/
+
+        f1.delete();
+        f2.delete();
+
+        /*No changes after adding a subset of files*/
+        ps.addAllFilesInDirectory( new File( "target/testAddAllFilesInDirectory" ), "123/" );
+        assertEquals( "Unexpected PathSet size", 4, ps.size() );
+
+        d1d2f1.delete();
+        d1d2f2.delete();
+        d1d2.delete();
+        d1.delete();
+        testDir.delete();
+
+        assertTrue( ps.contains( "123/f1" ) );
+        assertTrue( ps.contains( "/123/f1" ) );
+        assertTrue( ps.contains( "123\\f1" ) );
+        assertTrue( ps.contains( "123\\f2" ) );
+        assertTrue( ps.contains( "\\123/d1\\d2/f1" ) );
+        assertTrue( ps.contains( "123\\d1/d2\\f2" ) );
+        assertFalse( ps.contains( "123\\f3" ) );
+    }
+}
diff --git a/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/util/WebappStructureTest.java b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/util/WebappStructureTest.java
new file mode 100644
index 000000000..0e135de23
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/java/org/apache/maven/plugins/war/util/WebappStructureTest.java
@@ -0,0 +1,114 @@
+package org.apache.maven.plugins.war.util;
+
+/*
+ * 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.
+ */
+
+import junit.framework.TestCase;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.plugins.war.util.WebappStructure;
+
+import java.util.ArrayList;
+
+/**
+ * @author Stephane Nicoll
+ */
+public class WebappStructureTest
+    extends TestCase
+{
+    public void testUnknownFileNotAvailable()
+    {
+        final WebappStructure structure = new WebappStructure( new ArrayList<Dependency>() );
+        assertFalse( structure.isRegistered( "/foo/bar.txt" ) );
+    }
+
+    public void testRegisterSamePathTwice()
+    {
+        final WebappStructure structure = new WebappStructure( new ArrayList<Dependency>() );
+        structure.registerFile( "overlay1", "WEB-INF/web.xml" );
+        assertFalse( structure.registerFile( "currentBuild", "WEB-INF/web.xml" ) );
+    }
+
+    public void testRegisterForced()
+    {
+        final String path = "WEB-INF/web.xml";
+        final WebappStructure structure = new WebappStructure( new ArrayList<Dependency>() );
+        assertFalse("New file should return false",
+                    structure.registerFileForced( "overlay1", path ));
+        assertEquals( "overlay1", structure.getOwner( path ) );         
+    }
+
+    public void testRegisterSamePathTwiceForced()
+    {
+        final String path = "WEB-INF/web.xml";
+        final WebappStructure structure = new WebappStructure( new ArrayList<Dependency>() );
+        structure.registerFile( "overlay1", path );
+        assertEquals( "overlay1", structure.getOwner( path ) );
+        assertTrue("owner replacement should have returned true",
+                   structure.registerFileForced( "currentBuild", path ));
+        assertEquals("currentBuild", structure.getOwner( path ));
+    }
+
+
+    protected Dependency createDependency( String groupId, String artifactId, String version, String type, String scope,
+                                           String classifier )
+    {
+        final Dependency dep = new Dependency();
+        dep.setGroupId( groupId );
+        dep.setArtifactId( artifactId );
+        dep.setVersion( version );
+        if ( type == null )
+        {
+            dep.setType( "jar" );
+        }
+        else
+        {
+            dep.setType( type );
+        }
+        if ( scope != null )
+        {
+            dep.setScope( scope );
+        }
+        else
+        {
+            dep.setScope( Artifact.SCOPE_COMPILE );
+        }
+        if ( classifier != null )
+        {
+            dep.setClassifier( classifier );
+        }
+        return dep;
+    }
+
+    protected Dependency createDependency( String groupId, String artifactId, String version, String type,
+                                           String scope )
+    {
+        return createDependency( groupId, artifactId, version, type, scope, null );
+    }
+
+    protected Dependency createDependency( String groupId, String artifactId, String version, String type )
+    {
+        return createDependency( groupId, artifactId, version, type, null );
+    }
+
+    protected Dependency createDependency( String groupId, String artifactId, String version )
+    {
+        return createDependency( groupId, artifactId, version, null );
+    }
+}
diff --git a/Java-base/maven-war-plugin/src/src/test/resources/overlays/overlay-one/WEB-INF/web.xml b/Java-base/maven-war-plugin/src/src/test/resources/overlays/overlay-one/WEB-INF/web.xml
new file mode 100644
index 000000000..c39450400
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/resources/overlays/overlay-one/WEB-INF/web.xml
@@ -0,0 +1,21 @@
+<!--
+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.
+-->
+<web-app>
+  <display-name>Sample one overlay</display-name>
+</web-app>
diff --git a/Java-base/maven-war-plugin/src/src/test/resources/overlays/overlay-one/index.jsp b/Java-base/maven-war-plugin/src/src/test/resources/overlays/overlay-one/index.jsp
new file mode 100644
index 000000000..8846f183a
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/resources/overlays/overlay-one/index.jsp
@@ -0,0 +1,25 @@
+<!--
+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.
+-->
+<html>
+<body>
+<p>
+  Hello World, this is overlay-one!
+</p>
+</body>
+</html>
\ No newline at end of file
diff --git a/Java-base/maven-war-plugin/src/src/test/resources/overlays/overlay-one/login.jsp b/Java-base/maven-war-plugin/src/src/test/resources/overlays/overlay-one/login.jsp
new file mode 100644
index 000000000..96199c36e
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/resources/overlays/overlay-one/login.jsp
@@ -0,0 +1,21 @@
+<!--
+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.
+-->
+<html>
+
+</html>
\ No newline at end of file
diff --git a/Java-base/maven-war-plugin/src/src/test/resources/overlays/overlay-two/WEB-INF/web.xml b/Java-base/maven-war-plugin/src/src/test/resources/overlays/overlay-two/WEB-INF/web.xml
new file mode 100644
index 000000000..139f2c579
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/resources/overlays/overlay-two/WEB-INF/web.xml
@@ -0,0 +1,21 @@
+<!--
+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.
+-->
+<web-app>
+  <display-name>Sample two overlay</display-name>
+</web-app>
diff --git a/Java-base/maven-war-plugin/src/src/test/resources/overlays/overlay-two/admin.jsp b/Java-base/maven-war-plugin/src/src/test/resources/overlays/overlay-two/admin.jsp
new file mode 100644
index 000000000..96199c36e
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/resources/overlays/overlay-two/admin.jsp
@@ -0,0 +1,21 @@
+<!--
+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.
+-->
+<html>
+
+</html>
\ No newline at end of file
diff --git a/Java-base/maven-war-plugin/src/src/test/resources/overlays/overlay-two/index.jsp b/Java-base/maven-war-plugin/src/src/test/resources/overlays/overlay-two/index.jsp
new file mode 100644
index 000000000..d0fe77df5
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/resources/overlays/overlay-two/index.jsp
@@ -0,0 +1,25 @@
+<!--
+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.
+-->
+<html>
+<body>
+<p>
+  Hello World, this is overlay-two!
+</p>
+</body>
+</html>
\ No newline at end of file
diff --git a/Java-base/maven-war-plugin/src/src/test/resources/unit/sample_wars/ejb.jar b/Java-base/maven-war-plugin/src/src/test/resources/unit/sample_wars/ejb.jar
new file mode 100644
index 000000000..5ad4bcf96
Binary files /dev/null and b/Java-base/maven-war-plugin/src/src/test/resources/unit/sample_wars/ejb.jar differ
diff --git a/Java-base/maven-war-plugin/src/src/test/resources/unit/sample_wars/ejbclient.jar b/Java-base/maven-war-plugin/src/src/test/resources/unit/sample_wars/ejbclient.jar
new file mode 100644
index 000000000..5ad4bcf96
Binary files /dev/null and b/Java-base/maven-war-plugin/src/src/test/resources/unit/sample_wars/ejbclient.jar differ
diff --git a/Java-base/maven-war-plugin/src/src/test/resources/unit/sample_wars/include-exclude.war b/Java-base/maven-war-plugin/src/src/test/resources/unit/sample_wars/include-exclude.war
new file mode 100644
index 000000000..4f580db08
Binary files /dev/null and b/Java-base/maven-war-plugin/src/src/test/resources/unit/sample_wars/include-exclude.war differ
diff --git a/Java-base/maven-war-plugin/src/src/test/resources/unit/sample_wars/javax.servlet-api-3.0.1.jar b/Java-base/maven-war-plugin/src/src/test/resources/unit/sample_wars/javax.servlet-api-3.0.1.jar
new file mode 100644
index 000000000..4e2edcc9d
Binary files /dev/null and b/Java-base/maven-war-plugin/src/src/test/resources/unit/sample_wars/javax.servlet-api-3.0.1.jar differ
diff --git a/Java-base/maven-war-plugin/src/src/test/resources/unit/sample_wars/sample.par b/Java-base/maven-war-plugin/src/src/test/resources/unit/sample_wars/sample.par
new file mode 100644
index 000000000..e69de29bb
diff --git a/Java-base/maven-war-plugin/src/src/test/resources/unit/sample_wars/simple-updated.war b/Java-base/maven-war-plugin/src/src/test/resources/unit/sample_wars/simple-updated.war
new file mode 100644
index 000000000..58a5b76b2
Binary files /dev/null and b/Java-base/maven-war-plugin/src/src/test/resources/unit/sample_wars/simple-updated.war differ
diff --git a/Java-base/maven-war-plugin/src/src/test/resources/unit/sample_wars/simple.aar b/Java-base/maven-war-plugin/src/src/test/resources/unit/sample_wars/simple.aar
new file mode 100644
index 000000000..79681e07a
Binary files /dev/null and b/Java-base/maven-war-plugin/src/src/test/resources/unit/sample_wars/simple.aar differ
diff --git a/Java-base/maven-war-plugin/src/src/test/resources/unit/sample_wars/simple.jar b/Java-base/maven-war-plugin/src/src/test/resources/unit/sample_wars/simple.jar
new file mode 100644
index 000000000..79681e07a
Binary files /dev/null and b/Java-base/maven-war-plugin/src/src/test/resources/unit/sample_wars/simple.jar differ
diff --git a/Java-base/maven-war-plugin/src/src/test/resources/unit/sample_wars/simple.mar b/Java-base/maven-war-plugin/src/src/test/resources/unit/sample_wars/simple.mar
new file mode 100644
index 000000000..e69de29bb
diff --git a/Java-base/maven-war-plugin/src/src/test/resources/unit/sample_wars/simple.war b/Java-base/maven-war-plugin/src/src/test/resources/unit/sample_wars/simple.war
new file mode 100644
index 000000000..79681e07a
Binary files /dev/null and b/Java-base/maven-war-plugin/src/src/test/resources/unit/sample_wars/simple.war differ
diff --git a/Java-base/maven-war-plugin/src/src/test/resources/unit/sample_wars/simple.xar b/Java-base/maven-war-plugin/src/src/test/resources/unit/sample_wars/simple.xar
new file mode 100644
index 000000000..e69de29bb
diff --git a/Java-base/maven-war-plugin/src/src/test/resources/unit/sample_wars/tld.jar b/Java-base/maven-war-plugin/src/src/test/resources/unit/sample_wars/tld.jar
new file mode 100644
index 000000000..e69de29bb
diff --git a/Java-base/maven-war-plugin/src/src/test/resources/unit/warexplodedinplacemojo/plugin-config.xml b/Java-base/maven-war-plugin/src/src/test/resources/unit/warexplodedinplacemojo/plugin-config.xml
new file mode 100644
index 000000000..f5a51e6cd
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/resources/unit/warexplodedinplacemojo/plugin-config.xml
@@ -0,0 +1,31 @@
+<!--
+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.
+-->
+
+<project>
+  <name>war-plugin-test</name>
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-war-plugin</artifactId>
+        <configuration>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/Java-base/maven-war-plugin/src/src/test/resources/unit/warexplodedmojo/plugin-config.xml b/Java-base/maven-war-plugin/src/src/test/resources/unit/warexplodedmojo/plugin-config.xml
new file mode 100644
index 000000000..f5a51e6cd
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/resources/unit/warexplodedmojo/plugin-config.xml
@@ -0,0 +1,31 @@
+<!--
+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.
+-->
+
+<project>
+  <name>war-plugin-test</name>
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-war-plugin</artifactId>
+        <configuration>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/Java-base/maven-war-plugin/src/src/test/resources/unit/warmojotest/not-primary-artifact.xml b/Java-base/maven-war-plugin/src/src/test/resources/unit/warmojotest/not-primary-artifact.xml
new file mode 100644
index 000000000..902e78b33
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/resources/unit/warmojotest/not-primary-artifact.xml
@@ -0,0 +1,32 @@
+<!--
+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.
+-->
+
+<project>
+  <name>war-plugin-test</name>
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-war-plugin</artifactId>
+        <configuration>
+          <primaryArtifact>false</primaryArtifact>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/Java-base/maven-war-plugin/src/src/test/resources/unit/warmojotest/plugin-config-primary-artifact.xml b/Java-base/maven-war-plugin/src/src/test/resources/unit/warmojotest/plugin-config-primary-artifact.xml
new file mode 100644
index 000000000..684d0c79b
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/resources/unit/warmojotest/plugin-config-primary-artifact.xml
@@ -0,0 +1,32 @@
+<!--
+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.
+-->
+
+<project>
+  <name>war-plugin-test</name>
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-war-plugin</artifactId>
+        <configuration>
+          <primaryArtifact>true</primaryArtifact>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/Java-base/maven-war-plugin/src/src/test/resources/unit/waroverlays/default.xml b/Java-base/maven-war-plugin/src/src/test/resources/unit/waroverlays/default.xml
new file mode 100644
index 000000000..de295beaf
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/resources/unit/waroverlays/default.xml
@@ -0,0 +1,32 @@
+<!--
+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.
+-->
+
+<project>
+  <name>war-plugin-test</name>
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-war-plugin</artifactId>
+        <configuration>
+          <!-- no extra config so default is applied -->
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/Java-base/maven-war-plugin/src/src/test/resources/unit/warziptest/foobar.zip b/Java-base/maven-war-plugin/src/src/test/resources/unit/warziptest/foobar.zip
new file mode 100755
index 000000000..e1eb8480c
Binary files /dev/null and b/Java-base/maven-war-plugin/src/src/test/resources/unit/warziptest/foobar.zip differ
diff --git a/Java-base/maven-war-plugin/src/src/test/resources/unit/warziptest/war-with-zip.xml b/Java-base/maven-war-plugin/src/src/test/resources/unit/warziptest/war-with-zip.xml
new file mode 100644
index 000000000..9a3d425c8
--- /dev/null
+++ b/Java-base/maven-war-plugin/src/src/test/resources/unit/warziptest/war-with-zip.xml
@@ -0,0 +1,31 @@
+<!--
+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.
+-->
+
+<project>
+  <name>war-with-one-zip</name>
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-war-plugin</artifactId>
+        <configuration>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/Java-base/tiles-autotag/Dockerfile b/Java-base/tiles-autotag/Dockerfile
new file mode 100644
index 000000000..e208c4890
--- /dev/null
+++ b/Java-base/tiles-autotag/Dockerfile
@@ -0,0 +1,28 @@
+FROM ubuntu:22.04
+
+RUN export DEBIAN_FRONTEND=noninteractive \
+    && apt-get update \
+    && apt-get install -y software-properties-common \
+    && add-apt-repository ppa:deadsnakes/ppa \
+    && apt-get update \
+    && apt-get install -y \
+        build-essential \
+        git \
+        vim \
+        jq \
+    && apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/list/*
+
+RUN apt-get -y install sudo \
+      openjdk-8-jdk \
+      maven
+
+RUN bash -c "echo 2 | update-alternatives --config java"
+
+COPY src /workspace
+WORKDIR /workspace
+
+RUN mvn install -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false
+
+RUN mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100
+
+ENV TZ=Asia/Seoul
diff --git a/Java-base/tiles-autotag/src/FREEMARKER-LICENSE.txt b/Java-base/tiles-autotag/src/FREEMARKER-LICENSE.txt
new file mode 100644
index 000000000..ca617cb65
--- /dev/null
+++ b/Java-base/tiles-autotag/src/FREEMARKER-LICENSE.txt
@@ -0,0 +1,46 @@
+FreeMarker 1.x was released under the LGPL license. Later, by community
+consensus, we have switched over to a BSD-style license. As of FreeMarker
+2.2pre1, the original author, Benjamin Geer, has relinquished the copyright in
+behalf of Visigoth Software Society. The current copyright holder is the
+Visigoth Software Society.
+
+------------------------------------------------------------------------------
+Copyright (c) 2003 The Visigoth Software Society. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1.  Redistributions of source code must retain the above copyright notice,
+    this list of conditions and the following disclaimer.
+
+2.  The end-user documentation included with the redistribution, if any, must
+    include the following acknowlegement:
+      "This product includes software developed by the
+      Visigoth Software Society (http://www.visigoths.org/)."
+    Alternately, this acknowlegement may appear in the software itself, if and
+    wherever such third-party acknowlegements normally appear.
+
+3.  Neither the name "FreeMarker", "Visigoth", nor any of the names of the
+    project contributors may be used to endorse or promote products derived
+    from this software without prior written permission. For written
+    permission, please contact visigoths@visigoths.org.
+
+4.  Products derived from this software may not be called "FreeMarker" or
+    "Visigoth" nor may "FreeMarker" or "Visigoth" appear in their names
+    without prior written permission of the Visigoth Software Society.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+VISIGOTH SOFTWARE SOCIETY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+------------------------------------------------------------------------------
+
+This software consists of voluntary contributions made by many individuals on
+behalf of the Visigoth Software Society. For more information on the Visigoth
+Software Society, please see http://www.visigoths.org/
diff --git a/Java-base/tiles-autotag/src/NOTICE.txt b/Java-base/tiles-autotag/src/NOTICE.txt
new file mode 100644
index 000000000..dd3fc1a1b
--- /dev/null
+++ b/Java-base/tiles-autotag/src/NOTICE.txt
@@ -0,0 +1,11 @@
+   Apache Tiles Autotag
+   Copyright 1999-2012 The Apache Software Foundation
+
+   This product includes software developed at
+   The Apache Software Foundation (http://www.apache.org/).
+
+   The binary distribution contains software developed by:
+
+   Visigoth Software Society (Freemarker): http://freemarker.org/
+   Codehaus (QDox, XStream): http://mvel.codehaus.org/
+
diff --git a/Java-base/tiles-autotag/src/XSTREAM-LICENSE.txt b/Java-base/tiles-autotag/src/XSTREAM-LICENSE.txt
new file mode 100644
index 000000000..1ebc2d2f2
--- /dev/null
+++ b/Java-base/tiles-autotag/src/XSTREAM-LICENSE.txt
@@ -0,0 +1,27 @@
+Copyright (c) 2003-2006, Joe Walnes
+Copyright (c) 2006-2009, XStream Committers
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+Redistributions of source code must retain the above copyright notice, this list of
+conditions and the following disclaimer. Redistributions in binary form must reproduce
+the above copyright notice, this list of conditions and the following disclaimer in
+the documentation and/or other materials provided with the distribution.
+
+Neither the name of XStream nor the names of its contributors may be used to endorse
+or promote products derived from this software without specific prior written
+permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
+SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
+
diff --git a/Java-base/tiles-autotag/src/assembly/pom.xml b/Java-base/tiles-autotag/src/assembly/pom.xml
new file mode 100644
index 000000000..7aceb6b5d
--- /dev/null
+++ b/Java-base/tiles-autotag/src/assembly/pom.xml
@@ -0,0 +1,182 @@
+<?xml version="1.0"?>
+<!--
+    $Id: pom.xml 1333561 2012-05-03 17:24:51Z nlebas $
+
+    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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.apache.tiles</groupId>
+  <artifactId>tiles-autotag-assembly</artifactId>
+  <packaging>pom</packaging>
+  <name>Tiles Autotag Assembly</name>
+  <description>Tiles Autotag Assembly: assembles artifact to produce distributions.
+  </description>
+
+  <parent>
+    <groupId>org.apache.tiles</groupId>
+    <artifactId>tiles-autotag</artifactId>
+    <version>1.3-SNAPSHOT</version>
+  </parent>
+
+  <build>
+    <plugins>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-assembly-plugin</artifactId>
+          <version>3.1.0</version>
+        <configuration>
+          <descriptors>
+            <descriptor>src/main/assembly/bin.xml</descriptor>
+            <descriptor>src/main/assembly/docs.xml</descriptor>
+            <descriptor>src/main/assembly/src.xml</descriptor>
+          </descriptors>
+          <finalName>tiles-autotag-${project.version}</finalName>
+          <outputDirectory>target/assembly/out</outputDirectory>
+          <workDirectory>target/assembly/work</workDirectory>
+          <tarLongFileMode>gnu</tarLongFileMode>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <profiles>
+    <profile>
+      <id>apache-release</id>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-assembly-plugin</artifactId>
+            <version>3.1.0</version>
+            <executions>
+              <execution>
+                <id>make-assembly</id>
+                <goals>
+                  <goal>single</goal>
+                </goals>
+                <phase>package</phase>
+              </execution>
+            </executions>
+            <configuration>
+              <descriptors>
+                <descriptor>src/main/assembly/bin.xml</descriptor>
+                <descriptor>src/main/assembly/docs.xml</descriptor>
+                <descriptor>src/main/assembly/src.xml</descriptor>
+              </descriptors>
+              <tarLongFileMode>gnu</tarLongFileMode>
+            </configuration>
+          </plugin>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-deploy-plugin</artifactId>
+            <configuration>
+              <skip>true</skip>
+            </configuration>
+          </plugin>
+          <plugin>
+            <groupId>net.nicoulaj.maven.plugins</groupId>
+            <artifactId>checksum-maven-plugin</artifactId>
+            <version>1.6</version>
+            <executions>
+              <execution>
+                <goals>
+                  <goal>artifacts</goal>
+                </goals>
+              </execution>
+            </executions>
+            <configuration>
+                <attachChecksums>true</attachChecksums>
+            </configuration>
+          </plugin>
+          <plugin>
+              <groupId>org.apache.maven.plugins</groupId>
+              <artifactId>maven-gpg-plugin</artifactId>
+              <configuration>
+                  <ascDirectory>${project.build.directory}/..</ascDirectory>
+              </configuration>
+          </plugin>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-antrun-plugin</artifactId>
+            <version>1.8</version>
+            <executions>
+              <execution>
+                <phase>deploy</phase>
+                <goals>
+                  <goal>run</goal>
+                </goals>
+                <configuration>
+                  <tasks>
+                    <mkdir dir="${project.build.directory}/assemblies" />
+                    <echo message="Here I am!" />
+                    <copy todir="${project.build.directory}/assemblies">
+                      <fileset dir="${settings.localRepository}/org/apache/tiles/${project.artifactId}/${project.version}">
+                        <include name="${project.artifactId}-${project.version}-*.zip*" />
+                        <include name="${project.artifactId}-${project.version}-*.tar.gz*" />
+                        <exclude name="${project.artifactId}-${project.version}-source-release.*" />
+                      </fileset>
+                      <mapper type="glob" from="${project.artifactId}-*" to="tiles-autotag-*" />
+                    </copy>
+                  </tasks>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
+
+  <dependencies>
+
+    <dependency>
+      <groupId>org.apache.tiles</groupId>
+      <artifactId>tiles-autotag-core</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.tiles</groupId>
+      <artifactId>tiles-autotag-core-runtime</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.tiles</groupId>
+      <artifactId>tiles-autotag-jsp</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.tiles</groupId>
+      <artifactId>tiles-autotag-freemarker</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.tiles</groupId>
+      <artifactId>tiles-autotag-velocity</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.tiles.autotag.plugin</groupId>
+      <artifactId>maven-autotag-plugin</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+
+  </dependencies>
+
+</project>
diff --git a/Java-base/tiles-autotag/src/assembly/src/main/assembly/bin.xml b/Java-base/tiles-autotag/src/assembly/src/main/assembly/bin.xml
new file mode 100644
index 000000000..9f24948af
--- /dev/null
+++ b/Java-base/tiles-autotag/src/assembly/src/main/assembly/bin.xml
@@ -0,0 +1,53 @@
+<!--
+ 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.
+-->
+<assembly>
+    <id>bin</id>
+    <formats>
+        <format>tar.gz</format>
+        <format>zip</format>
+    </formats>
+    <includeSiteDirectory>false</includeSiteDirectory>
+    <dependencySets>
+        <dependencySet>
+            <outputDirectory>/lib</outputDirectory>
+            <outputFileNameMapping>${artifact.artifactId}-${artifact.version}${dashClassifier?}.${artifact.extension}</outputFileNameMapping>
+            <excludes>
+                <exclude>org.apache.tiles:*</exclude>
+                <exclude>org.apache.tiles.autotag.plugin:*</exclude>
+            </excludes>
+        </dependencySet>
+        <dependencySet>
+            <outputDirectory>/</outputDirectory>
+            <outputFileNameMapping>${artifact.artifactId}-${artifact.version}${dashClassifier?}.${artifact.extension}</outputFileNameMapping>
+            <includes>
+                <include>org.apache.tiles:*</include>
+                <include>org.apache.tiles.autotag.plugin:*</include>
+            </includes>
+        </dependencySet>
+    </dependencySets>
+
+    <fileSets>
+        <fileSet>
+            <directory>..</directory>
+            <outputDirectory>/</outputDirectory>
+            <includes>
+                <include>*LICENSE.*</include>
+                <include>NOTICE.txt</include>
+            </includes>
+        </fileSet>
+    </fileSets>
+</assembly>
diff --git a/Java-base/tiles-autotag/src/assembly/src/main/assembly/docs.xml b/Java-base/tiles-autotag/src/assembly/src/main/assembly/docs.xml
new file mode 100644
index 000000000..749f078c5
--- /dev/null
+++ b/Java-base/tiles-autotag/src/assembly/src/main/assembly/docs.xml
@@ -0,0 +1,41 @@
+<!--
+ 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.
+-->
+<assembly>
+    <id>docs</id>
+    <formats>
+        <format>tar.gz</format>
+        <format>zip</format>
+    </formats>
+    <includeSiteDirectory>false</includeSiteDirectory>
+    <dependencySets>
+    </dependencySets>
+
+    <fileSets>
+        <fileSet>
+            <directory>..</directory>
+            <outputDirectory>/</outputDirectory>
+            <includes>
+                <include>LICENSE.txt</include>
+                <include>NOTICE.txt</include>
+            </includes>
+        </fileSet>
+        <fileSet>
+            <directory>../target/site/apidocs</directory>
+            <outputDirectory>apidocs</outputDirectory>
+        </fileSet>
+    </fileSets>
+</assembly>
diff --git a/Java-base/tiles-autotag/src/assembly/src/main/assembly/src.xml b/Java-base/tiles-autotag/src/assembly/src/main/assembly/src.xml
new file mode 100644
index 000000000..02db183f3
--- /dev/null
+++ b/Java-base/tiles-autotag/src/assembly/src/main/assembly/src.xml
@@ -0,0 +1,98 @@
+<!--
+ 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.
+-->
+<assembly>
+    <id>src</id>
+    <formats>
+        <format>tar.gz</format>
+        <format>zip</format>
+    </formats>
+    <fileSets>
+        <fileSet>
+            <directory>../</directory>
+            <outputDirectory>src/</outputDirectory>
+            <includes>
+                <include>pom.xml</include>
+                <include>src/</include>
+            </includes>
+        </fileSet>
+        <fileSet>
+            <directory>../</directory>
+            <outputDirectory>/</outputDirectory>
+            <includes>
+                <include>LICENSE.txt</include>
+                <include>NOTICE.txt</include>
+            </includes>
+        </fileSet>
+
+        <fileSet>
+            <directory>../maven-autotag-plugin</directory>
+            <outputDirectory>src/maven-autotag-plugin</outputDirectory>
+            <includes>
+                <include>pom.xml</include>
+                <include>src/</include>
+            </includes>
+        </fileSet>
+        <fileSet>
+            <directory>../tiles-autotag-core</directory>
+            <outputDirectory>src/tiles-autotag-core</outputDirectory>
+            <includes>
+                <include>pom.xml</include>
+                <include>src/</include>
+            </includes>
+        </fileSet>
+        <fileSet>
+            <directory>../tiles-autotag-core-runtime</directory>
+            <outputDirectory>src/tiles-autotag-core-runtime</outputDirectory>
+            <includes>
+                <include>pom.xml</include>
+                <include>src/</include>
+            </includes>
+        </fileSet>
+        <fileSet>
+            <directory>../tiles-autotag-freemarker</directory>
+            <outputDirectory>src/tiles-autotag-freemarker</outputDirectory>
+            <includes>
+                <include>pom.xml</include>
+                <include>src/</include>
+            </includes>
+        </fileSet>
+        <fileSet>
+            <directory>../tiles-autotag-jsp</directory>
+            <outputDirectory>src/tiles-autotag-jsp</outputDirectory>
+            <includes>
+                <include>pom.xml</include>
+                <include>src/</include>
+            </includes>
+        </fileSet>
+        <fileSet>
+            <directory>../tiles-autotag-velocity</directory>
+            <outputDirectory>src/tiles-autotag-velocity</outputDirectory>
+            <includes>
+                <include>pom.xml</include>
+                <include>src/</include>
+            </includes>
+        </fileSet>
+        <fileSet>
+            <directory>../assembly</directory>
+            <outputDirectory>src/assembly</outputDirectory>
+            <includes>
+                <include>pom.xml</include>
+                <include>src/</include>
+            </includes>
+        </fileSet>
+    </fileSets>
+</assembly>
diff --git a/Java-base/tiles-autotag/src/assembly/src/main/resources/LICENSE.txt b/Java-base/tiles-autotag/src/assembly/src/main/resources/LICENSE.txt
new file mode 100644
index 000000000..d64569567
--- /dev/null
+++ b/Java-base/tiles-autotag/src/assembly/src/main/resources/LICENSE.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/Java-base/tiles-autotag/src/assembly/src/main/resources/NOTICE.txt b/Java-base/tiles-autotag/src/assembly/src/main/resources/NOTICE.txt
new file mode 100644
index 000000000..3ada21770
--- /dev/null
+++ b/Java-base/tiles-autotag/src/assembly/src/main/resources/NOTICE.txt
@@ -0,0 +1,6 @@
+   Apache Tiles
+   Copyright 1999-2009 The Apache Software Foundation
+
+   This product includes software developed at
+   The Apache Software Foundation (http://www.apache.org/).
+   
\ No newline at end of file
diff --git a/Java-base/tiles-autotag/src/assembly/src/site/site.xml b/Java-base/tiles-autotag/src/assembly/src/site/site.xml
new file mode 100644
index 000000000..0a48f7ee3
--- /dev/null
+++ b/Java-base/tiles-autotag/src/assembly/src/site/site.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+/*
+ * $Id: site.xml 1333561 2012-05-03 17:24:51Z nlebas $
+ *
+ * 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.
+ */
+-->
+<project name="Apache Tiles Autotag - Assembly">
+    <body>
+
+        <menu name="Apache Tiles&#8482; Autotag">
+            <item
+                   name="Home"
+                   href="../../index.html"/>
+            <item
+                   name="Parent module"
+                   href="../index.html"/>
+        </menu>
+
+        ${modules}
+        ${reports}
+
+    </body>
+</project>
diff --git a/Java-base/tiles-autotag/src/maven-autotag-plugin/pom.xml b/Java-base/tiles-autotag/src/maven-autotag-plugin/pom.xml
new file mode 100644
index 000000000..7eab75816
--- /dev/null
+++ b/Java-base/tiles-autotag/src/maven-autotag-plugin/pom.xml
@@ -0,0 +1,178 @@
+<?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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <artifactId>tiles-autotag</artifactId>
+    <groupId>org.apache.tiles</groupId>
+    <version>1.3-SNAPSHOT</version>
+  </parent>
+  <groupId>org.apache.tiles.autotag.plugin</groupId>
+  <artifactId>maven-autotag-plugin</artifactId>
+  <version>1.3-SNAPSHOT</version>
+  <packaging>maven-plugin</packaging>
+  <name>maven-autotag-plugin Maven Mojo</name>
+  <properties>
+        <!-- decrease this whenever possible -->
+        <checkstyle.maxAllowedViolations>71</checkstyle.maxAllowedViolations>
+  </properties>
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.maven</groupId>
+      <artifactId>maven-plugin-api</artifactId>
+      <version>2.2.1</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven.plugin-tools</groupId>
+      <artifactId>maven-plugin-annotations</artifactId>
+      <version>3.2</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.8.1</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+    	<groupId>org.sonatype.plexus</groupId>
+    	<artifactId>plexus-build-api</artifactId>
+    	<version>0.0.7</version>
+    </dependency>
+    <dependency>
+    	<groupId>org.apache.tiles</groupId>
+    	<artifactId>tiles-autotag-core</artifactId>
+    </dependency>
+    <dependency>
+    	<groupId>com.thoughtworks.xstream</groupId>
+    	<artifactId>xstream</artifactId>
+    	<version>1.3.1</version>
+    </dependency>
+    <dependency>
+    	<groupId>org.apache.tiles</groupId>
+    	<artifactId>tiles-autotag-jsp</artifactId>
+    	<version>1.3-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+    	<groupId>org.apache.maven</groupId>
+    	<artifactId>maven-core</artifactId>
+    	<version>2.2.1</version>
+    </dependency>
+    <dependency>
+    	<groupId>org.apache.maven</groupId>
+    	<artifactId>maven-model</artifactId>
+    	<version>2.2.1</version>
+    </dependency>
+    <dependency>
+    	<groupId>org.apache.maven</groupId>
+    	<artifactId>maven-project</artifactId>
+    	<version>2.2.1</version>
+    </dependency>
+    <dependency>
+    	<groupId>org.apache.maven</groupId>
+    	<artifactId>maven-artifact</artifactId>
+    	<version>2.2.1</version>
+    </dependency>
+    <dependency>
+    	<groupId>org.apache.tiles</groupId>
+    	<artifactId>tiles-autotag-freemarker</artifactId>
+    	<version>1.3-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+    	<groupId>org.apache.tiles</groupId>
+    	<artifactId>tiles-autotag-velocity</artifactId>
+    	<version>1.3-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+    	<groupId>org.easymock</groupId>
+    	<artifactId>easymock</artifactId>
+    	<type>jar</type>
+    	<scope>test</scope>
+    </dependency>
+    <dependency>
+    	<groupId>commons-io</groupId>
+    	<artifactId>commons-io</artifactId>
+    	<scope>test</scope>
+    </dependency>
+  </dependencies>
+  <build>
+  	<pluginManagement>
+  		<plugins>
+	      <plugin>
+	        <artifactId>maven-plugin-plugin</artifactId>
+	        <version>3.2</version>
+	        <configuration>
+	          <!-- see http://jira.codehaus.org/browse/MNG-5346 -->
+	          <skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
+	        </configuration>
+	        <executions>
+	          <execution>
+	            <id>default-descriptor</id>
+	            <phase>process-classes</phase>
+	            <goals>
+	              <goal>descriptor</goal>
+	            </goals>
+	          </execution>
+	          <execution>
+	            <id>default-addPluginArtifactMetadata</id>
+	            <phase>package</phase>
+	            <goals>
+	              <goal>addPluginArtifactMetadata</goal>
+	            </goals>
+	          </execution>
+	        </executions>
+	      </plugin>
+  			<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
+  			<plugin>
+  				<groupId>org.eclipse.m2e</groupId>
+  				<artifactId>lifecycle-mapping</artifactId>
+  				<version>1.0.0</version>
+  				<configuration>
+  					<lifecycleMappingMetadata>
+  						<pluginExecutions>
+  							<pluginExecution>
+  								<pluginExecutionFilter>
+  									<groupId>
+  										org.apache.maven.plugins
+  									</groupId>
+  									<artifactId>
+  										maven-plugin-plugin
+  									</artifactId>
+  									<versionRange>
+  										[3.2,)
+  									</versionRange>
+  									<goals>
+  										<goal>descriptor</goal>
+  									</goals>
+  								</pluginExecutionFilter>
+  								<action>
+  									<ignore />
+  								</action>
+  							</pluginExecution>
+  						</pluginExecutions>
+  					</lifecycleMappingMetadata>
+  				</configuration>
+  			</plugin>
+  		</plugins>
+  	</pluginManagement>
+  </build>
+</project>
diff --git a/Java-base/tiles-autotag/src/maven-autotag-plugin/src/main/java/org/apache/tiles/autotag/plugin/AbstractGenerateMojo.java b/Java-base/tiles-autotag/src/maven-autotag-plugin/src/main/java/org/apache/tiles/autotag/plugin/AbstractGenerateMojo.java
new file mode 100644
index 000000000..a3988ccef
--- /dev/null
+++ b/Java-base/tiles-autotag/src/maven-autotag-plugin/src/main/java/org/apache/tiles/autotag/plugin/AbstractGenerateMojo.java
@@ -0,0 +1,233 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.plugin;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.net.URLConnection;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.maven.model.Resource;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugins.annotations.Component;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.project.MavenProject;
+import org.apache.tiles.autotag.core.OutputLocator;
+import org.apache.tiles.autotag.generate.TemplateGenerator;
+import org.apache.tiles.autotag.generate.TemplateGeneratorFactory;
+import org.apache.tiles.autotag.model.TemplateSuite;
+import org.apache.velocity.app.VelocityEngine;
+import org.sonatype.plexus.build.incremental.BuildContext;
+
+import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.converters.reflection.Sun14ReflectionProvider;
+
+/**
+ * Abstract class to generate boilerplate code starting from template model classes.
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class AbstractGenerateMojo extends AbstractMojo {
+	/**
+     * The position of the template suite XML descriptor.
+     */
+    static final String META_INF_TEMPLATE_SUITE_XML = "META-INF/template-suite.xml";
+
+    /**
+     * The classpath elements.
+     */
+    @Parameter(property = "project.compileClasspathElements", required = true, readonly = true)
+    List<String> classpathElements;
+
+    /**
+     * Location of the generated classes.
+     */
+	@Parameter(defaultValue = "${project.build.directory}/autotag-classes", required = true)
+	File classesOutputDirectory;
+
+    /**
+     * Location of the generated resources.
+     */
+	@Parameter(defaultValue = "${project.build.directory}/autotag-resources", required = true)
+    File resourcesOutputDirectory;
+
+    /**
+     * Name of the request class.
+     */
+	@Parameter(defaultValue = "org.apache.tiles.request.Request", required = true)
+    String requestClass;
+
+    /**
+     * Name of the package.
+     */
+	@Parameter(required = true)
+    String packageName;
+
+	@Component
+    MavenProject project;
+
+	@Component
+    BuildContext buildContext;
+
+	OutputLocator classesOutputLocator;
+	OutputLocator resourcesOutputLocator;
+	
+    /** {@inheritDoc} */
+    public void execute() throws MojoExecutionException {
+        try {
+        	TemplateSuite suite;
+        	URLConnection templateSuite = findTemplateSuiteDescriptor();
+        	long lastModified = templateSuite.getLastModified();
+        	InputStream stream = templateSuite.getInputStream();
+            try {
+	            XStream xstream = new XStream(new Sun14ReflectionProvider());
+	            suite = (TemplateSuite) xstream.fromXML(stream);
+            } finally {
+	            stream.close();
+            }
+            classesOutputLocator = new MavenOutputLocator(classesOutputDirectory, lastModified);
+            resourcesOutputLocator = new MavenOutputLocator(resourcesOutputDirectory, lastModified);
+            Properties props = new Properties();
+            InputStream propsStream = getClass().getResourceAsStream("/org/apache/tiles/autotag/velocity.properties");
+            props.load(propsStream);
+            propsStream.close();
+            TemplateGenerator generator = createTemplateGeneratorFactory(
+                    new VelocityEngine(props)).createTemplateGenerator();
+            generator.generate(packageName, suite, getParameters(), getRuntimeClass(), requestClass);
+            if (generator.isGeneratingResources()) {
+            	buildContext.refresh(resourcesOutputDirectory);
+                addResourceDirectory(resourcesOutputDirectory.getAbsolutePath());
+            }
+            if (generator.isGeneratingClasses()) {
+            	buildContext.refresh(classesOutputDirectory);
+                addCompileSourceRoot(classesOutputDirectory.getAbsolutePath());
+            }
+        } catch (IOException e) {
+            throw new MojoExecutionException("error", e);
+        } catch (RuntimeException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new MojoExecutionException("error", e);
+        }
+    }
+
+	private void addResourceDirectory(String directory) {
+		boolean addResource = true;
+		@SuppressWarnings("unchecked")
+		List<Resource> resources = project.getResources();
+		for(Resource resource: resources) {
+			if(directory.equals(resource.getDirectory())) {
+				addResource = false;
+			}
+		}
+		if(addResource) {
+		    Resource resource = new Resource();
+		    resource.setDirectory(directory);
+		    project.addResource(resource);
+		}
+	}
+
+	private void addCompileSourceRoot(String directory) {
+		boolean addResource = true;
+		@SuppressWarnings("unchecked")
+		List<String> roots = project.getCompileSourceRoots();
+		for(String root: roots) {
+			if(directory.equals(root)) {
+				addResource = false;
+			}
+		}
+		if(addResource) {
+		    project.addCompileSourceRoot(directory);
+		}
+	}
+
+
+	/**
+     * Creates a template generator factory.
+     *
+     * @param velocityEngine The Velocity engine.
+     * @return The template generator factory.
+     */
+    protected abstract TemplateGeneratorFactory createTemplateGeneratorFactory(VelocityEngine velocityEngine);
+
+    /**
+     * Returns the map of parameters.
+     *
+     * @return The parameters.
+     */
+    protected abstract Map<String, String> getParameters();
+
+    /**
+     * Searches for the template suite descriptor in all dependencies and sources.
+     *
+     * @return The inputstream of the identified descriptor.
+     * @throws IOException If something goes wrong.
+     */
+    private URLConnection findTemplateSuiteDescriptor() throws IOException {
+        URL[] urls = new URL[classpathElements.size()];
+        int i = 0;
+        for ( String classpathElement: classpathElements )
+        {
+            urls[i++] = new File(classpathElement).toURI().toURL();
+        }
+
+        ClassLoader cl = new URLClassLoader( urls );
+        return cl.getResource(META_INF_TEMPLATE_SUITE_XML).openConnection();
+    }
+
+    /**
+     * Name of the Runtime class.
+     * @return The name of the Runtime class.
+     */
+    protected abstract String getRuntimeClass();
+
+    private final class MavenOutputLocator implements OutputLocator {
+    	
+    	private File outputDirectory;
+    	private long sourceLastModified;
+    	
+    	private MavenOutputLocator(File outputDirectory, long sourceLastModified) {
+    		this.outputDirectory = outputDirectory;
+    		this.sourceLastModified = sourceLastModified;
+    	}
+    	
+		@Override
+		public OutputStream getOutputStream(String resourcePath)
+				throws IOException {
+			File target = new File(outputDirectory, resourcePath);
+			target.getParentFile().mkdirs();
+			return buildContext.newFileOutputStream(target);
+		}
+
+		@Override
+		public boolean isUptodate(String resourcePath) {
+			File target = new File(outputDirectory, resourcePath);
+			return target.exists() && target.lastModified() > sourceLastModified;
+		}
+	}
+}
diff --git a/Java-base/tiles-autotag/src/maven-autotag-plugin/src/main/java/org/apache/tiles/autotag/plugin/CreateDescriptorMojo.java b/Java-base/tiles-autotag/src/maven-autotag-plugin/src/main/java/org/apache/tiles/autotag/plugin/CreateDescriptorMojo.java
new file mode 100644
index 000000000..93e8db49d
--- /dev/null
+++ b/Java-base/tiles-autotag/src/maven-autotag-plugin/src/main/java/org/apache/tiles/autotag/plugin/CreateDescriptorMojo.java
@@ -0,0 +1,198 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.plugin;
+
+/*
+ * Copyright 2001-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.maven.model.Resource;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugins.annotations.Component;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.project.MavenProject;
+import org.apache.tiles.autotag.core.QDoxTemplateSuiteFactory;
+import org.apache.tiles.autotag.model.TemplateSuite;
+import org.codehaus.plexus.util.Scanner;
+import org.sonatype.plexus.build.incremental.BuildContext;
+
+import com.thoughtworks.xstream.XStream;
+
+/**
+ * Creates a descriptor for the template model in XML format.
+ */
+@Mojo(name = "create-descriptor", defaultPhase = LifecyclePhase.GENERATE_RESOURCES)
+public class CreateDescriptorMojo extends AbstractMojo {
+    /**
+     * Location of the file.
+     */
+	@Parameter(defaultValue = "${project.build.directory}/autotag-template-suite", required = true)
+    File outputDirectory;
+
+    /**
+     * Location of the file.
+     */
+	@Parameter(property = "project.build.sourceDirectory", required = true)
+    File sourceDirectory;
+
+    /**
+     * included files.
+     */
+	@Parameter
+    Set<String> includes;
+
+    /**
+     * The name of the template.
+     */
+	@Parameter(required = true)
+    String name;
+
+    /**
+     * The documentation of the suite.
+     */
+	@Parameter
+    String documentation;
+
+    /**
+     * Excluded files.
+     */
+	@Parameter
+    Set<String> excludes;
+
+    /**
+     * Name of the request class.
+     */
+	@Parameter(defaultValue="org.apache.tiles.request.Request", required = true)
+    String requestClass;
+
+	@Parameter(property = "project", required = true, readonly = true)
+    MavenProject project;
+
+	@Component
+    BuildContext buildContext;
+
+    /** {@inheritDoc} */
+    public void execute() throws MojoExecutionException {
+        try {
+            String[] fileNames = getSourceInclusionScanner().getIncludedFiles();
+            File dir = new File(outputDirectory, "META-INF");
+            if(!dir.exists()) {
+            	dir.mkdirs();
+            	buildContext.refresh(dir);
+            }
+            File outputFile = new File(dir, "template-suite.xml");
+            boolean uptodate = outputFile.exists();
+            File[] files = new File[fileNames.length];
+            for(int i=0; i<fileNames.length; i++) {
+            	files[i] = new File(sourceDirectory, fileNames[i]);
+            	uptodate &= buildContext.isUptodate(outputFile, files[i]);
+            }
+            if(!uptodate) {
+                createDescriptor(outputFile, files);
+			}
+            addResourceDirectory(outputDirectory.getAbsolutePath());
+        } catch (IOException e) {
+            throw new MojoExecutionException("error", e);
+        }
+    }
+
+	private void createDescriptor(File outputFile, File[] files)
+			throws IOException {
+		QDoxTemplateSuiteFactory factory = new QDoxTemplateSuiteFactory(files);
+		factory.setSuiteName(name);
+		factory.setSuiteDocumentation(documentation);
+		factory.setRequestClass(requestClass);
+		TemplateSuite suite = factory.createTemplateSuite();
+		XStream xstream = new XStream();
+		OutputStream os = buildContext.newFileOutputStream(outputFile);
+		Writer writer = new OutputStreamWriter(os);
+		xstream.toXML(suite, writer);
+		writer.close();
+		os.close();
+	}
+
+	private void addResourceDirectory(String directory) {
+		boolean addResource = true;
+		@SuppressWarnings("unchecked")
+		List<Resource> resources = project.getResources();
+		for(Resource resource: resources) {
+			if(directory.equals(resource.getDirectory())) {
+				addResource = false;
+			}
+		}
+		if(addResource) {
+		    Resource resource = new Resource();
+		    resource.setDirectory(directory);
+		    project.addResource(resource);
+		}
+	}
+
+    /**
+     * Creates a source inclusion scanner.
+     *
+     * @return The inclusion scanner.
+     */
+    private Scanner getSourceInclusionScanner() {
+    	Scanner scanner = buildContext.newScanner( sourceDirectory );
+        if (includes == null) {
+            includes = new HashSet<String>();
+        }
+        if (excludes == null) {
+            excludes = new HashSet<String>();
+        }
+
+        if (includes.isEmpty()) {
+            scanner.setIncludes(new String[] {"**/*Model.java"});
+        }
+        else {
+        	scanner.setIncludes(includes.toArray(new String[includes.size()]));
+        }
+        if (!excludes.isEmpty()) {
+        	scanner.setExcludes(excludes.toArray(new String[excludes.size()]));
+        }
+        scanner.scan();
+        return scanner;
+    }
+}
diff --git a/Java-base/tiles-autotag/src/maven-autotag-plugin/src/main/java/org/apache/tiles/autotag/plugin/GenerateFreemarkerMojo.java b/Java-base/tiles-autotag/src/maven-autotag-plugin/src/main/java/org/apache/tiles/autotag/plugin/GenerateFreemarkerMojo.java
new file mode 100644
index 000000000..a938fa631
--- /dev/null
+++ b/Java-base/tiles-autotag/src/maven-autotag-plugin/src/main/java/org/apache/tiles/autotag/plugin/GenerateFreemarkerMojo.java
@@ -0,0 +1,67 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.plugin;
+
+import java.util.Map;
+
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.plugins.annotations.ResolutionScope;
+import org.apache.tiles.autotag.freemarker.FMTemplateGeneratorFactory;
+import org.apache.tiles.autotag.generate.TemplateGeneratorBuilder;
+import org.apache.tiles.autotag.generate.TemplateGeneratorFactory;
+import org.apache.velocity.app.VelocityEngine;
+
+/**
+ * Generates Freemarker code.
+ */
+@Mojo(
+	name = "generate-freemarker",
+	defaultPhase = LifecyclePhase.GENERATE_SOURCES,
+	requiresDependencyResolution = ResolutionScope.COMPILE)
+public class GenerateFreemarkerMojo extends AbstractGenerateMojo {
+
+    /**
+     * Name of the Runtime.
+     */
+	@Parameter(defaultValue = "org.apache.tiles.autotag.freemarker.runtime.Runtime", required = true)
+    String freemarkerRuntime;
+
+    /** {@inheritDoc} */
+    @Override
+    protected Map<String, String> getParameters() {
+        return null;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected String getRuntimeClass() {
+        return freemarkerRuntime;
+    }
+
+    @Override
+    protected TemplateGeneratorFactory createTemplateGeneratorFactory(
+            VelocityEngine velocityEngine) {
+        return new FMTemplateGeneratorFactory(classesOutputLocator,
+                velocityEngine, TemplateGeneratorBuilder.createNewInstance());
+    }
+}
diff --git a/Java-base/tiles-autotag/src/maven-autotag-plugin/src/main/java/org/apache/tiles/autotag/plugin/GenerateJspMojo.java b/Java-base/tiles-autotag/src/maven-autotag-plugin/src/main/java/org/apache/tiles/autotag/plugin/GenerateJspMojo.java
new file mode 100644
index 000000000..e69897e77
--- /dev/null
+++ b/Java-base/tiles-autotag/src/maven-autotag-plugin/src/main/java/org/apache/tiles/autotag/plugin/GenerateJspMojo.java
@@ -0,0 +1,94 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.plugin;
+
+/*
+ * Copyright 2001-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.plugins.annotations.ResolutionScope;
+import org.apache.tiles.autotag.generate.TemplateGeneratorBuilder;
+import org.apache.tiles.autotag.generate.TemplateGeneratorFactory;
+import org.apache.tiles.autotag.jsp.JspTemplateGeneratorFactory;
+import org.apache.velocity.app.VelocityEngine;
+
+
+/**
+ * Goal which touches a timestamp file.
+ */
+@Mojo(
+	name = "generate-jsp",
+	defaultPhase = LifecyclePhase.GENERATE_SOURCES,
+	requiresDependencyResolution = ResolutionScope.COMPILE)
+public class GenerateJspMojo extends AbstractGenerateMojo {
+
+    /**
+     * URI of the tag library.
+     */
+	@Parameter(required = true)
+    String taglibURI;
+
+    /**
+     * Name of the Runtime.
+     */
+	@Parameter(defaultValue = "org.apache.tiles.autotag.jsp.runtime.Runtime", required = true)
+    String jspRuntime;
+
+    /** {@inheritDoc} */
+    @Override
+    protected Map<String, String> getParameters() {
+        Map<String, String> params = new HashMap<String, String>();
+        params.put("taglibURI", taglibURI);
+        return params;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected String getRuntimeClass() {
+        return jspRuntime;
+    }
+
+    @Override
+    protected TemplateGeneratorFactory createTemplateGeneratorFactory(
+            VelocityEngine velocityEngine) {
+        return new JspTemplateGeneratorFactory(classesOutputLocator,
+                resourcesOutputLocator, velocityEngine,
+                TemplateGeneratorBuilder.createNewInstance());
+    }
+}
diff --git a/Java-base/tiles-autotag/src/maven-autotag-plugin/src/main/java/org/apache/tiles/autotag/plugin/GenerateVelocityMojo.java b/Java-base/tiles-autotag/src/maven-autotag-plugin/src/main/java/org/apache/tiles/autotag/plugin/GenerateVelocityMojo.java
new file mode 100644
index 000000000..de7ab82cc
--- /dev/null
+++ b/Java-base/tiles-autotag/src/maven-autotag-plugin/src/main/java/org/apache/tiles/autotag/plugin/GenerateVelocityMojo.java
@@ -0,0 +1,85 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.plugin;
+
+/*
+ * Copyright 2001-2005 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.Map;
+
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.plugins.annotations.ResolutionScope;
+import org.apache.tiles.autotag.generate.TemplateGeneratorBuilder;
+import org.apache.tiles.autotag.generate.TemplateGeneratorFactory;
+import org.apache.tiles.autotag.velocity.VelocityTemplateGeneratorFactory;
+import org.apache.velocity.app.VelocityEngine;
+
+
+/**
+ * Generates Velocity code.
+ */
+@Mojo(
+	name = "generate-velocity",
+	defaultPhase = LifecyclePhase.GENERATE_SOURCES,
+	requiresDependencyResolution = ResolutionScope.COMPILE)
+public class GenerateVelocityMojo extends AbstractGenerateMojo {
+
+    /**
+     * Name of the Runtime.
+     */
+	@Parameter(defaultValue = "org.apache.tiles.autotag.velocity.runtime.Runtime", required = true)
+    String velocityRuntime;
+
+    /** {@inheritDoc} */
+    @Override
+    protected Map<String, String> getParameters() {
+        return null;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected String getRuntimeClass() {
+        return velocityRuntime;
+    }
+
+    @Override
+    protected TemplateGeneratorFactory createTemplateGeneratorFactory(
+            VelocityEngine velocityEngine) {
+        return new VelocityTemplateGeneratorFactory(classesOutputLocator,
+                resourcesOutputLocator, velocityEngine,
+                TemplateGeneratorBuilder.createNewInstance());
+    }
+}
diff --git a/Java-base/tiles-autotag/src/maven-autotag-plugin/src/main/java/org/apache/tiles/autotag/plugin/package-info.java b/Java-base/tiles-autotag/src/maven-autotag-plugin/src/main/java/org/apache/tiles/autotag/plugin/package-info.java
new file mode 100644
index 000000000..e25ccb08c
--- /dev/null
+++ b/Java-base/tiles-autotag/src/maven-autotag-plugin/src/main/java/org/apache/tiles/autotag/plugin/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * Contains the autotag mojos.
+ */
+package org.apache.tiles.autotag.plugin;
diff --git a/Java-base/tiles-autotag/src/maven-autotag-plugin/src/main/resources/META-INF/m2e/lifecycle-mapping-metadata.xml b/Java-base/tiles-autotag/src/maven-autotag-plugin/src/main/resources/META-INF/m2e/lifecycle-mapping-metadata.xml
new file mode 100644
index 000000000..1014adf56
--- /dev/null
+++ b/Java-base/tiles-autotag/src/maven-autotag-plugin/src/main/resources/META-INF/m2e/lifecycle-mapping-metadata.xml
@@ -0,0 +1,78 @@
+<!--
+/*
+ * $Id:  $
+ *
+ * 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.
+ */
+ -->
+<lifecycleMappingMetadata>
+  <pluginExecutions>
+    <pluginExecution>
+      <pluginExecutionFilter>
+        <goals>
+          <goal>create-descriptor</goal>
+        </goals>
+      </pluginExecutionFilter>
+      <action>
+        <execute>
+          <runOnConfiguration>true</runOnConfiguration>
+          <runOnIncremental>true</runOnIncremental>
+        </execute>
+      </action>
+    </pluginExecution>
+    <pluginExecution>
+      <pluginExecutionFilter>
+        <goals>
+          <goal>generate-freemarker</goal>
+        </goals>
+      </pluginExecutionFilter>
+      <action>
+        <execute>
+          <runOnConfiguration>true</runOnConfiguration>
+          <runOnIncremental>true</runOnIncremental>
+        </execute>
+      </action>
+    </pluginExecution>
+    <pluginExecution>
+      <pluginExecutionFilter>
+        <goals>
+          <goal>generate-jsp</goal>
+        </goals>
+      </pluginExecutionFilter>
+      <action>
+        <execute>
+          <runOnConfiguration>true</runOnConfiguration>
+          <runOnIncremental>true</runOnIncremental>
+        </execute>
+      </action>
+    </pluginExecution>
+    <pluginExecution>
+      <pluginExecutionFilter>
+        <goals>
+          <goal>generate-velocity</goal>
+        </goals>
+      </pluginExecutionFilter>
+      <action>
+        <execute>
+          <runOnConfiguration>true</runOnConfiguration>
+          <runOnIncremental>true</runOnIncremental>
+        </execute>
+      </action>
+    </pluginExecution>
+  </pluginExecutions>
+</lifecycleMappingMetadata>
diff --git a/Java-base/tiles-autotag/src/maven-autotag-plugin/src/site/site.xml b/Java-base/tiles-autotag/src/maven-autotag-plugin/src/site/site.xml
new file mode 100644
index 000000000..0a7d00df4
--- /dev/null
+++ b/Java-base/tiles-autotag/src/maven-autotag-plugin/src/site/site.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+/*
+ * $Id: site.xml 1081442 2011-03-14 16:21:08Z apetrelli $
+ *
+ * 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.
+ */
+-->
+<project name="Apache - Tiles Autotags">
+    <bannerLeft>
+        <name>Apache Software Foundation</name>
+        <src>http://www.apache.org/images/asf-logo.gif</src>
+        <href>http://www.apache.org</href>
+    </bannerLeft>
+    <bannerRight>
+        <name>Apache Tiles&#8482;</name>
+        <src>http://tiles.apache.org/images/logo.png</src>
+        <href>http://tiles.apache.org</href>
+    </bannerRight>
+    <body>
+
+        <links>
+            <item name="Apache" href="http://www.apache.org" />
+            <item name="Tiles" href="http://tiles.apache.org" />
+        </links>
+
+
+        <menu name="Apache Tiles&#8482;">
+            <item
+                   name="Tiles Home"
+                   href="../../index.html"/>
+            <item
+                   name="Tiles Autotag"
+                   href="../index.html"/>
+        </menu>
+
+        <menu ref="modules" />
+        <menu ref="reports" />
+
+    </body>
+</project>
diff --git a/Java-base/tiles-autotag/src/maven-autotag-plugin/src/test/java/org/apache/tiles/autotag/plugin/AbstractGenerateMojoTest.java b/Java-base/tiles-autotag/src/maven-autotag-plugin/src/test/java/org/apache/tiles/autotag/plugin/AbstractGenerateMojoTest.java
new file mode 100644
index 000000000..412b0c1ea
--- /dev/null
+++ b/Java-base/tiles-autotag/src/maven-autotag-plugin/src/test/java/org/apache/tiles/autotag/plugin/AbstractGenerateMojoTest.java
@@ -0,0 +1,102 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.plugin;
+
+import static org.easymock.EasyMock.*;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.maven.model.Resource;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.project.MavenProject;
+import org.apache.tiles.autotag.generate.TemplateGenerator;
+import org.apache.tiles.autotag.generate.TemplateGeneratorFactory;
+import org.apache.tiles.autotag.model.TemplateSuite;
+import org.apache.velocity.app.VelocityEngine;
+import org.junit.Test;
+import org.sonatype.plexus.build.incremental.BuildContext;
+
+/**
+ * Tests {@link AbstractGenerateMojo}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class AbstractGenerateMojoTest {
+
+    /**
+     * Tests {@link AbstractGenerateMojo#execute()}.
+     * @throws IOException If something goes wrong.
+     * @throws MojoExecutionException If something goes wrong.
+     */
+    @Test
+    public void testExecute() throws IOException, MojoExecutionException {
+        MavenProject mavenProject = createMock(MavenProject.class);
+        BuildContext buildContext = createMock(BuildContext.class);
+        TemplateGeneratorFactory factory = createMock(TemplateGeneratorFactory.class);
+        TemplateGenerator generator = createMock(TemplateGenerator.class);
+        @SuppressWarnings("unchecked")
+        Map<String, String> params = createMock(Map.class);
+        AbstractGenerateMojo mojo = createMockBuilder(AbstractGenerateMojo.class).createMock();
+        List<String> classpathElements = new ArrayList<String>();
+        File source = new File(System.getProperty("basedir"), "src/test/resources");
+        classpathElements.add(source.getAbsolutePath());
+        mojo.classpathElements = classpathElements;
+        File temp = File.createTempFile("autotagmojogen", ".tmp");
+        temp.delete();
+        temp.mkdirs();
+        File resourcesOutputDirectory = new File(temp, "res/");
+        File classesOutputDirectory = new File(temp, "classes/");
+        resourcesOutputDirectory.mkdir();
+        classesOutputDirectory.mkdir();
+        mojo.resourcesOutputDirectory = resourcesOutputDirectory;
+        mojo.classesOutputDirectory = classesOutputDirectory;
+        mojo.packageName = "my.package";
+        mojo.project = mavenProject;
+        mojo.requestClass = "my.package.Request";
+        mojo.buildContext = buildContext;
+
+        buildContext.refresh(isA(File.class));
+        expectLastCall().times(2);
+        expect(mojo.createTemplateGeneratorFactory(isA(VelocityEngine.class))).andReturn(factory);
+        expect(factory.createTemplateGenerator()).andReturn(generator);
+        expect(mojo.getParameters()).andReturn(params);
+        expect(mojo.getRuntimeClass()).andReturn("my.package.Runtime");
+        generator.generate(eq("my.package"), isA(TemplateSuite.class), eq(params), eq("my.package.Runtime"), eq("my.package.Request"));
+        expect(generator.isGeneratingClasses()).andReturn(true);
+        expect(generator.isGeneratingResources()).andReturn(true);
+        expect(mavenProject.getResources()).andReturn(Collections.emptyList());
+        mavenProject.addResource(isA(Resource.class));
+        expect(mavenProject.getCompileSourceRoots()).andReturn(Collections.emptyList());
+        mavenProject.addCompileSourceRoot(classesOutputDirectory.getAbsolutePath());
+
+        replay(mavenProject, buildContext, mojo, factory, generator, params);
+        mojo.execute();
+        FileUtils.deleteDirectory(temp);
+        verify(mavenProject, buildContext, mojo, factory, generator, params);
+    }
+
+}
diff --git a/Java-base/tiles-autotag/src/maven-autotag-plugin/src/test/java/org/apache/tiles/autotag/plugin/CreateDescriptorMojoTest.java b/Java-base/tiles-autotag/src/maven-autotag-plugin/src/test/java/org/apache/tiles/autotag/plugin/CreateDescriptorMojoTest.java
new file mode 100644
index 000000000..70b470c66
--- /dev/null
+++ b/Java-base/tiles-autotag/src/maven-autotag-plugin/src/test/java/org/apache/tiles/autotag/plugin/CreateDescriptorMojoTest.java
@@ -0,0 +1,203 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.plugin;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.isA;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.maven.model.Resource;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.project.MavenProject;
+import org.apache.tiles.autotag.core.runtime.ModelBody;
+import org.apache.tiles.autotag.model.TemplateClass;
+import org.apache.tiles.autotag.model.TemplateMethod;
+import org.apache.tiles.autotag.model.TemplateParameter;
+import org.apache.tiles.autotag.model.TemplateSuite;
+import org.apache.tiles.autotag.plugin.internal.AnnotatedExampleModel;
+import org.apache.tiles.autotag.plugin.internal.ExampleExecutableModel;
+import org.apache.tiles.autotag.plugin.internal.ExampleModel;
+import org.apache.tiles.autotag.plugin.internal.ExampleRequest;
+import org.apache.tiles.autotag.plugin.internal.NotFeasibleExampleModel;
+import org.codehaus.plexus.util.Scanner;
+import org.junit.Test;
+import org.sonatype.plexus.build.incremental.BuildContext;
+
+import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.converters.reflection.Sun14ReflectionProvider;
+
+/**
+ * Tests {@link CreateDescriptorMojo}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class CreateDescriptorMojoTest {
+
+    /**
+     * Test method for {@link org.apache.tiles.autotag.plugin.CreateDescriptorMojo#execute()}.
+     * @throws IOException If something goes wrong.
+     * @throws MojoExecutionException If something goes wrong.
+     */
+    @Test
+    public void testExecute() throws IOException, MojoExecutionException {
+        MavenProject mavenProject = createMock(MavenProject.class);
+        BuildContext buildContext = createMock(BuildContext.class);
+        Scanner scanner = createMock(Scanner.class);
+
+        CreateDescriptorMojo mojo = new CreateDescriptorMojo();
+        mojo.sourceDirectory = new File(System.getProperty("basedir"), "src/test/java");
+        String[] models = getModels(mojo.sourceDirectory);
+        File temp = File.createTempFile("autotagmojo", ".tmp");
+        temp.delete();
+        temp.mkdirs();
+        mojo.outputDirectory = temp;
+        mojo.name = "test";
+        mojo.documentation = "This are the docs";
+        mojo.project = mavenProject;
+        mojo.requestClass = ExampleRequest.class.getName();
+        mojo.buildContext = buildContext;
+
+        expect(mavenProject.getResources()).andReturn(Collections.emptyList());
+        mavenProject.addResource(isA(Resource.class));
+        expect(buildContext.newScanner(isA(File.class))).andReturn(scanner);
+        scanner.setIncludes(isA(String[].class));
+        scanner.scan();
+        expect(scanner.getIncludedFiles()).andReturn(models);
+        File file = new File(temp, "META-INF/template-suite.xml");
+        file.getParentFile().mkdirs();
+        expect(buildContext.isUptodate(isA(File.class), isA(File.class))).andReturn(false).times(models.length);
+        expect(buildContext.newFileOutputStream(isA(File.class))).andReturn(new FileOutputStream(file));
+        replay(mavenProject, buildContext, scanner);
+        mojo.execute();
+        InputStream sis = new FileInputStream(new File(temp, "META-INF/template-suite.xml"));
+        XStream xstream = new XStream(new Sun14ReflectionProvider());
+        TemplateSuite suite = (TemplateSuite) xstream.fromXML(sis);
+        sis.close();
+        assertEquals("test", suite.getName());
+        assertEquals("This are the docs", suite.getDocumentation());
+        assertEquals(3, suite.getTemplateClasses().size());
+
+        TemplateClass templateClass = suite.getTemplateClassByName(ExampleModel.class.getName());
+        assertNotNull(templateClass);
+        assertEquals(ExampleModel.class.getName(), templateClass.getName());
+        assertEquals("Example start/stop template.", templateClass.getDocumentation());
+        TemplateMethod templateMethod = templateClass.getExecuteMethod();
+        assertNotNull(templateMethod);
+        assertTrue(templateMethod.hasBody());
+        assertTrue(templateClass.hasBody());
+        assertEquals("execute", templateMethod.getName());
+        assertEquals("It starts.", templateMethod.getDocumentation());
+        List<TemplateParameter> parameters = new ArrayList<TemplateParameter>(templateMethod.getParameters());
+        assertEquals(4, parameters.size());
+        TemplateParameter parameter = parameters.get(0);
+        assertEquals("one", parameter.getName());
+        assertEquals("java.lang.String", parameter.getType());
+        assertEquals("Parameter one.", parameter.getDocumentation());
+        parameter = parameters.get(1);
+        assertEquals("two", parameter.getName());
+        assertEquals("int", parameter.getType());
+        assertEquals("Parameter two.", parameter.getDocumentation());
+        parameter = parameters.get(2);
+        assertEquals("request", parameter.getName());
+        assertEquals(ExampleRequest.class.getName(), parameter.getType());
+        assertEquals("The request.", parameter.getDocumentation());
+        parameter = parameters.get(3);
+        assertEquals("modelBody", parameter.getName());
+        assertEquals(ModelBody.class.getName(), parameter.getType());
+        assertEquals("The model body.", parameter.getDocumentation());
+
+        templateClass = suite.getTemplateClassByName(AnnotatedExampleModel.class.getName());
+        assertNotNull(templateClass);
+        assertEquals(AnnotatedExampleModel.class.getName(), templateClass.getName());
+        templateMethod = templateClass.getExecuteMethod();
+        assertNotNull(templateMethod);
+        assertEquals("execute", templateMethod.getName());
+        parameters = new ArrayList<TemplateParameter>(templateMethod.getParameters());
+        assertEquals(4, parameters.size());
+        parameter = parameters.get(0);
+        assertEquals("one", parameter.getName());
+        assertEquals("alternateOne", parameter.getExportedName());
+        assertEquals("java.lang.String", parameter.getType());
+        assertEquals("Parameter one.", parameter.getDocumentation());
+        assertEquals("hello", parameter.getDefaultValue());
+        assertTrue(parameter.isRequired());
+
+        templateClass = suite.getTemplateClassByName(ExampleExecutableModel.class.getName());
+        assertNotNull(templateClass);
+        assertEquals(ExampleExecutableModel.class.getName(), templateClass.getName());
+        assertEquals("Example executable template.", templateClass.getDocumentation());
+        templateMethod = templateClass.getExecuteMethod();
+        assertNotNull(templateMethod);
+        assertEquals("execute", templateMethod.getName());
+        assertEquals("It executes.", templateMethod.getDocumentation());
+        parameters = new ArrayList<TemplateParameter>(templateMethod.getParameters());
+        assertEquals(3, parameters.size());
+        parameter = parameters.get(0);
+        assertEquals("one", parameter.getName());
+        assertEquals("java.lang.String", parameter.getType());
+        assertEquals("Parameter one.", parameter.getDocumentation());
+        parameter = parameters.get(1);
+        assertEquals("two", parameter.getName());
+        assertEquals("int", parameter.getType());
+        assertEquals("Parameter two.", parameter.getDocumentation());
+        parameter = parameters.get(2);
+        assertEquals("request", parameter.getName());
+        assertEquals(ExampleRequest.class.getName(), parameter.getType());
+        assertEquals("The request.", parameter.getDocumentation());
+
+        assertNull(suite.getTemplateClassByName(NotFeasibleExampleModel.class.getName()));
+        FileUtils.deleteDirectory(temp);
+        verify(mavenProject, buildContext);
+    }
+
+	private String[] getModels(File sourceDirectory) {
+		File modelDir = new File(sourceDirectory, "org/apache/tiles/autotag/plugin/internal/");
+        String[] models = modelDir.list(new FilenameFilter() {
+			
+			@Override
+			public boolean accept(File dir, String name) {
+				return name.endsWith("Model.java");
+			}
+		});
+        for(int i = 0; i<models.length; i++) {
+        	models[i] = "org/apache/tiles/autotag/plugin/internal/" + models[i];
+        }
+		return models;
+	}
+
+}
diff --git a/Java-base/tiles-autotag/src/maven-autotag-plugin/src/test/java/org/apache/tiles/autotag/plugin/GenerateFreemarkerMojoTest.java b/Java-base/tiles-autotag/src/maven-autotag-plugin/src/test/java/org/apache/tiles/autotag/plugin/GenerateFreemarkerMojoTest.java
new file mode 100644
index 000000000..767cc38a3
--- /dev/null
+++ b/Java-base/tiles-autotag/src/maven-autotag-plugin/src/test/java/org/apache/tiles/autotag/plugin/GenerateFreemarkerMojoTest.java
@@ -0,0 +1,53 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.plugin;
+
+import static org.junit.Assert.*;
+
+import org.apache.tiles.autotag.freemarker.FMTemplateGeneratorFactory;
+import org.junit.Test;
+
+/**
+ * Tests {@link GenerateFreemarkerMojo}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class GenerateFreemarkerMojoTest {
+
+    /**
+     * Test method for {@link GenerateFreemarkerMojo#createTemplateGeneratorFactory(VelocityEngine)}.
+     */
+    @Test
+    public void testCreateTemplateGeneratorFactory() {
+        GenerateFreemarkerMojo mojo = new GenerateFreemarkerMojo();
+        assertTrue(mojo.createTemplateGeneratorFactory(null) instanceof FMTemplateGeneratorFactory);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.autotag.plugin.GenerateFreemarkerMojo#getParameters()}.
+     */
+    @Test
+    public void testGetParameters() {
+        GenerateFreemarkerMojo mojo = new GenerateFreemarkerMojo();
+        assertNull(mojo.getParameters());
+    }
+
+}
diff --git a/Java-base/tiles-autotag/src/maven-autotag-plugin/src/test/java/org/apache/tiles/autotag/plugin/GenerateJspMojoTest.java b/Java-base/tiles-autotag/src/maven-autotag-plugin/src/test/java/org/apache/tiles/autotag/plugin/GenerateJspMojoTest.java
new file mode 100644
index 000000000..40e4a66c8
--- /dev/null
+++ b/Java-base/tiles-autotag/src/maven-autotag-plugin/src/test/java/org/apache/tiles/autotag/plugin/GenerateJspMojoTest.java
@@ -0,0 +1,54 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.plugin;
+
+import static org.junit.Assert.*;
+
+import org.apache.tiles.autotag.jsp.JspTemplateGeneratorFactory;
+import org.junit.Test;
+
+/**
+ * Tests {@link GenerateJspMojo}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class GenerateJspMojoTest {
+
+    /**
+     * Test method for {@link GenerateJspMojo#createTemplateGeneratorFactory(VelocityEngine)}.
+     */
+    @Test
+    public void testCreateTemplateGeneratorFactory() {
+        GenerateJspMojo mojo = new GenerateJspMojo();
+        assertTrue(mojo.createTemplateGeneratorFactory(null) instanceof JspTemplateGeneratorFactory);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.autotag.plugin.GenerateJspMojo#getParameters()}.
+     */
+    @Test
+    public void testGetParameters() {
+        GenerateJspMojo mojo = new GenerateJspMojo();
+        mojo.taglibURI = "http://www.test.org/taglib";
+        assertEquals("http://www.test.org/taglib", mojo.getParameters().get("taglibURI"));
+    }
+
+}
diff --git a/Java-base/tiles-autotag/src/maven-autotag-plugin/src/test/java/org/apache/tiles/autotag/plugin/GenerateVelocityMojoTest.java b/Java-base/tiles-autotag/src/maven-autotag-plugin/src/test/java/org/apache/tiles/autotag/plugin/GenerateVelocityMojoTest.java
new file mode 100644
index 000000000..4f859ce43
--- /dev/null
+++ b/Java-base/tiles-autotag/src/maven-autotag-plugin/src/test/java/org/apache/tiles/autotag/plugin/GenerateVelocityMojoTest.java
@@ -0,0 +1,53 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.plugin;
+
+import static org.junit.Assert.*;
+
+import org.apache.tiles.autotag.velocity.VelocityTemplateGeneratorFactory;
+import org.junit.Test;
+
+/**
+ * Tests {@link GenerateVelocityMojo}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class GenerateVelocityMojoTest {
+
+    /**
+     * Test method for {@link GenerateVelocityMojo#createTemplateGeneratorFactory(VelocityEngine)}.
+     */
+    @Test
+    public void testCreateTemplateGeneratorFactory() {
+        GenerateVelocityMojo mojo = new GenerateVelocityMojo();
+        assertTrue(mojo.createTemplateGeneratorFactory(null) instanceof VelocityTemplateGeneratorFactory);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.autotag.plugin.GenerateVelocityMojo#getParameters()}.
+     */
+    @Test
+    public void testGetParameters() {
+        GenerateVelocityMojo mojo = new GenerateVelocityMojo();
+        assertNull(mojo.getParameters());
+    }
+
+}
diff --git a/Java-base/tiles-autotag/src/maven-autotag-plugin/src/test/java/org/apache/tiles/autotag/plugin/internal/AnnotatedExampleModel.java b/Java-base/tiles-autotag/src/maven-autotag-plugin/src/test/java/org/apache/tiles/autotag/plugin/internal/AnnotatedExampleModel.java
new file mode 100644
index 000000000..10dadc4ae
--- /dev/null
+++ b/Java-base/tiles-autotag/src/maven-autotag-plugin/src/test/java/org/apache/tiles/autotag/plugin/internal/AnnotatedExampleModel.java
@@ -0,0 +1,46 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.plugin.internal;
+
+import org.apache.tiles.autotag.core.runtime.ModelBody;
+import org.apache.tiles.autotag.core.runtime.annotation.Parameter;
+
+/**
+ * Example start/stop template.
+ *
+ * @version $Rev$ $Date$
+ */
+public class AnnotatedExampleModel {
+
+    /**
+     * It starts.
+     *
+     * @param one Parameter one.
+     * @param two Parameter two.
+     * @param request The request.
+     * @param modelBody The model body.
+     */
+    public void execute(
+            @Parameter(defaultValue = "hello", name = "alternateOne", required = true) String one,
+            int two, ExampleRequest request, ModelBody modelBody) {
+        // Does nothing.
+    }
+}
diff --git a/Java-base/tiles-autotag/src/maven-autotag-plugin/src/test/java/org/apache/tiles/autotag/plugin/internal/ExampleExcluded.java b/Java-base/tiles-autotag/src/maven-autotag-plugin/src/test/java/org/apache/tiles/autotag/plugin/internal/ExampleExcluded.java
new file mode 100644
index 000000000..68404e835
--- /dev/null
+++ b/Java-base/tiles-autotag/src/maven-autotag-plugin/src/test/java/org/apache/tiles/autotag/plugin/internal/ExampleExcluded.java
@@ -0,0 +1,43 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.plugin.internal;
+
+import org.apache.tiles.autotag.core.runtime.ModelBody;
+
+/**
+ * Example start/stop template.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ExampleExcluded {
+
+    /**
+     * It starts.
+     *
+     * @param one Parameter one.
+     * @param two Parameter two.
+     * @param request The request.
+     * @param modelBody The model body.
+     */
+    public void execute(String one, int two, ExampleRequest request, ModelBody modelBody) {
+        // Does nothing.
+    }
+}
diff --git a/Java-base/tiles-autotag/src/maven-autotag-plugin/src/test/java/org/apache/tiles/autotag/plugin/internal/ExampleExecutableModel.java b/Java-base/tiles-autotag/src/maven-autotag-plugin/src/test/java/org/apache/tiles/autotag/plugin/internal/ExampleExecutableModel.java
new file mode 100644
index 000000000..15a3d1e88
--- /dev/null
+++ b/Java-base/tiles-autotag/src/maven-autotag-plugin/src/test/java/org/apache/tiles/autotag/plugin/internal/ExampleExecutableModel.java
@@ -0,0 +1,40 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.plugin.internal;
+
+/**
+ * Example executable template.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ExampleExecutableModel {
+
+    /**
+     * It executes.
+     *
+     * @param one Parameter one.
+     * @param two Parameter two.
+     * @param request The request.
+     */
+    public void execute(String one, int two, ExampleRequest request) {
+        // Does nothing.
+    }
+}
diff --git a/Java-base/tiles-autotag/src/maven-autotag-plugin/src/test/java/org/apache/tiles/autotag/plugin/internal/ExampleModel.java b/Java-base/tiles-autotag/src/maven-autotag-plugin/src/test/java/org/apache/tiles/autotag/plugin/internal/ExampleModel.java
new file mode 100644
index 000000000..506683bc4
--- /dev/null
+++ b/Java-base/tiles-autotag/src/maven-autotag-plugin/src/test/java/org/apache/tiles/autotag/plugin/internal/ExampleModel.java
@@ -0,0 +1,43 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.plugin.internal;
+
+import org.apache.tiles.autotag.core.runtime.ModelBody;
+
+/**
+ * Example start/stop template.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ExampleModel {
+
+    /**
+     * It starts.
+     *
+     * @param one Parameter one.
+     * @param two Parameter two.
+     * @param request The request.
+     * @param modelBody The model body.
+     */
+    public void execute(String one, int two, ExampleRequest request, ModelBody modelBody) {
+        // Does nothing.
+    }
+}
diff --git a/Java-base/tiles-autotag/src/maven-autotag-plugin/src/test/java/org/apache/tiles/autotag/plugin/internal/ExampleRequest.java b/Java-base/tiles-autotag/src/maven-autotag-plugin/src/test/java/org/apache/tiles/autotag/plugin/internal/ExampleRequest.java
new file mode 100644
index 000000000..8a580739b
--- /dev/null
+++ b/Java-base/tiles-autotag/src/maven-autotag-plugin/src/test/java/org/apache/tiles/autotag/plugin/internal/ExampleRequest.java
@@ -0,0 +1,25 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.plugin.internal;
+
+public class ExampleRequest {
+
+}
diff --git a/Java-base/tiles-autotag/src/maven-autotag-plugin/src/test/java/org/apache/tiles/autotag/plugin/internal/NotFeasibleExampleModel.java b/Java-base/tiles-autotag/src/maven-autotag-plugin/src/test/java/org/apache/tiles/autotag/plugin/internal/NotFeasibleExampleModel.java
new file mode 100644
index 000000000..a52eb6202
--- /dev/null
+++ b/Java-base/tiles-autotag/src/maven-autotag-plugin/src/test/java/org/apache/tiles/autotag/plugin/internal/NotFeasibleExampleModel.java
@@ -0,0 +1,38 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.plugin.internal;
+
+/**
+ * This won't be registered.
+ *
+ * @version $Rev$ $Date$
+ */
+public class NotFeasibleExampleModel {
+
+    /**
+     * It starts.
+     *
+     * @param whatever Doesn't matter.
+     */
+    public void start(String whatever) {
+        // Does nothing.
+    }
+}
diff --git a/Java-base/tiles-autotag/src/maven-autotag-plugin/src/test/resources/META-INF/template-suite.xml b/Java-base/tiles-autotag/src/maven-autotag-plugin/src/test/resources/META-INF/template-suite.xml
new file mode 100644
index 000000000..de0a13375
--- /dev/null
+++ b/Java-base/tiles-autotag/src/maven-autotag-plugin/src/test/resources/META-INF/template-suite.xml
@@ -0,0 +1,183 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+ -->
+<org.apache.tiles.autotag.model.TemplateSuite>
+  <name>test</name>
+  <templateClasses class="linked-hash-map">
+    <entry>
+      <string>org.apache.tiles.autotag.plugin.internal.ExampleExecutableModel</string>
+      <org.apache.tiles.autotag.model.TemplateClass>
+        <name>org.apache.tiles.autotag.plugin.internal.ExampleExecutableModel</name>
+        <tagName>exampleExecutable</tagName>
+        <tagClassPrefix>ExampleExecutable</tagClassPrefix>
+        <documentation>Example executable template.</documentation>
+        <executeMethod>
+          <name>execute</name>
+          <documentation>It executes.</documentation>
+          <parameters class="linked-hash-map">
+            <entry>
+              <string>one</string>
+              <org.apache.tiles.autotag.model.TemplateParameter>
+                <name>one</name>
+                <exportedName>one</exportedName>
+                <documentation>Parameter one.</documentation>
+                <type>java.lang.String</type>
+                <required>false</required>
+              </org.apache.tiles.autotag.model.TemplateParameter>
+            </entry>
+            <entry>
+              <string>two</string>
+              <org.apache.tiles.autotag.model.TemplateParameter>
+                <name>two</name>
+                <exportedName>two</exportedName>
+                <documentation>Parameter two.</documentation>
+                <type>int</type>
+                <required>false</required>
+              </org.apache.tiles.autotag.model.TemplateParameter>
+            </entry>
+            <entry>
+              <string>request</string>
+              <org.apache.tiles.autotag.model.TemplateParameter>
+                <name>request</name>
+                <exportedName>request</exportedName>
+                <documentation>The request.</documentation>
+                <type>org.apache.tiles.request.Request</type>
+                <required>false</required>
+              </org.apache.tiles.autotag.model.TemplateParameter>
+            </entry>
+          </parameters>
+        </executeMethod>
+      </org.apache.tiles.autotag.model.TemplateClass>
+    </entry>
+    <entry>
+      <string>org.apache.tiles.autotag.plugin.internal.ExampleModel</string>
+      <org.apache.tiles.autotag.model.TemplateClass>
+        <name>org.apache.tiles.autotag.plugin.internal.ExampleModel</name>
+        <tagName>example</tagName>
+        <tagClassPrefix>Example</tagClassPrefix>
+        <documentation>Example start/stop template.</documentation>
+        <executeMethod>
+          <name>execute</name>
+          <documentation>It starts.</documentation>
+          <parameters class="linked-hash-map">
+            <entry>
+              <string>one</string>
+              <org.apache.tiles.autotag.model.TemplateParameter>
+                <name>one</name>
+                <exportedName>one</exportedName>
+                <documentation>Parameter one.</documentation>
+                <type>java.lang.String</type>
+                <required>false</required>
+              </org.apache.tiles.autotag.model.TemplateParameter>
+            </entry>
+            <entry>
+              <string>two</string>
+              <org.apache.tiles.autotag.model.TemplateParameter>
+                <name>two</name>
+                <exportedName>two</exportedName>
+                <documentation>Parameter two.</documentation>
+                <type>int</type>
+                <required>false</required>
+              </org.apache.tiles.autotag.model.TemplateParameter>
+            </entry>
+            <entry>
+              <string>request</string>
+              <org.apache.tiles.autotag.model.TemplateParameter>
+                <name>request</name>
+                <exportedName>request</exportedName>
+                <documentation>The request.</documentation>
+                <type>org.apache.tiles.request.Request</type>
+                <required>false</required>
+              </org.apache.tiles.autotag.model.TemplateParameter>
+            </entry>
+            <entry>
+              <string>modelBody</string>
+              <org.apache.tiles.autotag.model.TemplateParameter>
+                <name>modelBody</name>
+                <exportedName>modelBody</exportedName>
+                <documentation>The model body.</documentation>
+                <type>org.apache.tiles.autotag.core.runtime.ModelBody</type>
+                <required>false</required>
+              </org.apache.tiles.autotag.model.TemplateParameter>
+            </entry>
+          </parameters>
+        </executeMethod>
+      </org.apache.tiles.autotag.model.TemplateClass>
+    </entry>
+    <entry>
+      <string>org.apache.tiles.autotag.plugin.internal.AnnotatedExampleModel</string>
+      <org.apache.tiles.autotag.model.TemplateClass>
+        <name>org.apache.tiles.autotag.plugin.internal.AnnotatedExampleModel</name>
+        <tagName>annotatedExample</tagName>
+        <tagClassPrefix>AnnotatedExample</tagClassPrefix>
+        <documentation>Example start/stop template.</documentation>
+        <executeMethod>
+          <name>execute</name>
+          <documentation>It starts.</documentation>
+          <parameters class="linked-hash-map">
+            <entry>
+              <string>one</string>
+              <org.apache.tiles.autotag.model.TemplateParameter>
+                <name>one</name>
+                <exportedName>alternateOne</exportedName>
+                <documentation>Parameter one.</documentation>
+                <type>java.lang.String</type>
+                <defaultValue>hello</defaultValue>
+                <required>true</required>
+              </org.apache.tiles.autotag.model.TemplateParameter>
+            </entry>
+            <entry>
+              <string>two</string>
+              <org.apache.tiles.autotag.model.TemplateParameter>
+                <name>two</name>
+                <exportedName>two</exportedName>
+                <documentation>Parameter two.</documentation>
+                <type>int</type>
+                <required>false</required>
+              </org.apache.tiles.autotag.model.TemplateParameter>
+            </entry>
+            <entry>
+              <string>request</string>
+              <org.apache.tiles.autotag.model.TemplateParameter>
+                <name>request</name>
+                <exportedName>request</exportedName>
+                <documentation>The request.</documentation>
+                <type>org.apache.tiles.request.Request</type>
+                <required>false</required>
+              </org.apache.tiles.autotag.model.TemplateParameter>
+            </entry>
+            <entry>
+              <string>modelBody</string>
+              <org.apache.tiles.autotag.model.TemplateParameter>
+                <name>modelBody</name>
+                <exportedName>modelBody</exportedName>
+                <documentation>The model body.</documentation>
+                <type>org.apache.tiles.autotag.core.runtime.ModelBody</type>
+                <required>false</required>
+              </org.apache.tiles.autotag.model.TemplateParameter>
+            </entry>
+          </parameters>
+        </executeMethod>
+      </org.apache.tiles.autotag.model.TemplateClass>
+    </entry>
+  </templateClasses>
+</org.apache.tiles.autotag.model.TemplateSuite>
\ No newline at end of file
diff --git a/Java-base/tiles-autotag/src/pom.xml b/Java-base/tiles-autotag/src/pom.xml
new file mode 100644
index 000000000..1e9437adf
--- /dev/null
+++ b/Java-base/tiles-autotag/src/pom.xml
@@ -0,0 +1,199 @@
+<?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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <artifactId>tiles-master</artifactId>
+        <groupId>org.apache.tiles</groupId>
+        <version>7</version>
+    </parent>
+
+    <!-- temporary only while parent pom is snapshot -->
+  <repositories>
+    <repository>
+      <releases>
+        <enabled>false</enabled>
+      </releases>
+      <id>apache.snapshots</id>
+      <name>Apache Snapshot Repository</name>
+      <url>https://repository.apache.org/snapshots</url>
+    </repository>
+  </repositories>
+
+    <groupId>org.apache.tiles</groupId>
+    <artifactId>tiles-autotag</artifactId>
+    <version>1.3-SNAPSHOT</version>
+    <packaging>pom</packaging>
+    <name>Autotags</name>
+    <description>Automatic generation of tags.</description>
+    <url>http://tiles.apache.org/tiles-autotag/</url>
+    <scm>
+        <connection>scm:svn:http://svn.apache.org/repos/asf/tiles/autotag/trunk/</connection>
+        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/tiles/autotag/trunk/</developerConnection>
+        <url>http://svn.apache.org/viewvc/tiles/autotag/trunk/</url>
+    </scm>
+    <issueManagement>
+        <system>JIRA</system>
+        <url>https://issues.apache.org/jira/browse/AUTOTAG</url>
+        <!-- dev@tiles.apache.org :: this line satisfies INFRA-3329 -->
+    </issueManagement>
+
+    <modules>
+        <module>tiles-autotag-core-runtime</module>
+        <module>tiles-autotag-core</module>
+        <module>tiles-autotag-jsp</module>
+        <module>tiles-autotag-freemarker</module>
+        <module>tiles-autotag-velocity</module>
+        <module>maven-autotag-plugin</module>
+        <module>assembly</module>
+    </modules>
+    <distributionManagement>
+        <site>
+            <id>apache-site</id>
+            <url>scm:svn:https://svn.apache.org/repos/asf/tiles/site/staging/tiles-autotag</url>
+        </site>
+    </distributionManagement>
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>junit</groupId>
+                <artifactId>junit</artifactId>
+                <version>4.7</version>
+                <scope>test</scope>
+            </dependency>
+            <dependency>
+                <groupId>com.thoughtworks.qdox</groupId>
+                <artifactId>qdox</artifactId>
+                <version>1.10.1</version>
+            </dependency>
+            <dependency>
+                <groupId>org.easymock</groupId>
+                <artifactId>easymock</artifactId>
+                <version>3.0</version>
+                <scope>test</scope>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.tiles</groupId>
+                <artifactId>tiles-autotag-core</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.tiles</groupId>
+                <artifactId>tiles-autotag-core-runtime</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.velocity</groupId>
+                <artifactId>velocity</artifactId>
+                <version>1.6.3</version>
+            </dependency>
+            <dependency>
+                <groupId>commons-io</groupId>
+                <artifactId>commons-io</artifactId>
+                <version>2.0</version>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+    <build>
+        <plugins>
+            <plugin>
+              <groupId>org.apache.maven.plugins</groupId>
+              <artifactId>maven-scm-publish-plugin</artifactId>
+              <extensions>true</extensions>
+                <configuration>
+                    <pubScmUrl>scm:svn:https://svn.apache.org/repos/asf/tiles/site/staging/tiles-autotag</pubScmUrl>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+    <properties>
+        <maven.javadoc.failOnError>false</maven.javadoc.failOnError> <!-- remove with master-8 -->
+    </properties>
+
+    <profiles>
+        <profile>
+            <id>apache-release</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <artifactId>maven-install-plugin</artifactId>
+                        <configuration>
+                            <createChecksum>true</createChecksum>
+                        </configuration>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>rat-maven-plugin</artifactId>
+                        <version>1.0-alpha-3</version>
+                        <executions>
+                            <execution>
+                                <phase>verify</phase>
+                                <goals>
+                                    <goal>check</goal>
+                                </goals>
+                                <configuration>
+                                    <addDefaultLicenseMatchers>false</addDefaultLicenseMatchers>
+                                    <licenseMatchers>
+                                        <classNames>
+                                            <className>rat.analysis.license.ApacheSoftwareLicense20</className>
+                                        </classNames>
+                                        <classNames>
+                                            <className>rat.analysis.generation.GeneratedLicenseNotRequired</className>
+                                        </classNames>
+                                    </licenseMatchers>
+                                    <includes>
+                                        <include>pom.xml</include>
+                                        <include>src/**</include>
+                                    </includes>
+                                    <excludes>
+                                        <exclude>**/*LICENSE.txt</exclude>
+                                        <exclude>**/*MANIFEST.MF</exclude>
+                                    </excludes>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+        <profile>
+            <id>linkcheck</id>
+            <reporting>
+                <plugins>
+                    <plugin>
+                        <artifactId>maven-linkcheck-plugin</artifactId>
+                        <version>1.1</version>
+                        <configuration>
+                            <excludedLinks>
+                                <excludedLink>**/index.html</excludedLink>
+                                <excludedLink>**/logo.png</excludedLink>
+                            </excludedLinks>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </reporting>
+        </profile>
+
+    </profiles>
+
+</project>
diff --git a/Java-base/tiles-autotag/src/src/site/apt/dev/release.apt b/Java-base/tiles-autotag/src/src/site/apt/dev/release.apt
new file mode 100644
index 000000000..c78171261
--- /dev/null
+++ b/Java-base/tiles-autotag/src/src/site/apt/dev/release.apt
@@ -0,0 +1,302 @@
+~~ $Id$
+~~
+~~ 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.
+~~
+         -----------
+         Release Process
+         -----------
+
+Tiles Release Process
+
+  Here you will find the steps to create releases for Tiles.
+
+  Apache's existing documentation should be read
+
+  * {{{http://www.apache.org/dev/release-publishing}Publishing Releases}}
+
+  * {{{http://www.apache.org/dev/publishing-maven-artifacts.html}Publishing Maven Artifacts}}
+
+  * {{{http://www.apache.org/dev/release}Releases Policy}}
+
+Prerequisites
+
+  To create a release you have to install:
+
+  * {{{http://www.oracle.com/technetwork/java/javase/overview/index.html}Java 9}}. If you are using a newer
+  version of Java <<change JAVA_HOME environment variable>>
+  when calling Maven, so it points to an instance of Java 9;
+
+  * {{{http://maven.apache.org/}Maven 3.2.2+}};
+
+  * {{{http://www.gnupg.org/}GnuPG}};
+
+  * {{{http://www.openssh.com/}OpenSSH}};
+
+  * {{{http://www.graphviz.org/}GraphViz}};
+
+One-time operations
+
+  These operations need to be performed only one time.
+
+* Create and publish your GPG key
+
+  To create a GPG key, follow the
+  {{{http://www.apache.org/dev/openpgp.html}guidelines}}.
+  Include it in:
+
+-------------------------------------
+https://svn.apache.org/repos/asf/tiles/site/KEYS
+-------------------------------------
+
+  Publish your GPG key in a PGP key server, such as
+  {{{http://pgp.mit.edu/} MIT Keyserver}}.
+
+* Modify <<<settings.xml>>>
+
+  Your <<<settings.xml>>> must be modified to allow deployment.
+
+  See {{{http://www.apache.org/dev/publishing-maven-artifacts.html#dev-env}Publishing Maven Artifacts – Setup your development environment}}
+
+Repeatable operations
+
+  These steps must be performed <<for each>> release.
+
+* Prepare the release tag
+
+  To prepare the release Subversion tag, check out the branch/trunk from where
+  you are preparing the release and type:
+
+-----------------------------------
+mvn clean
+mvn release:prepare -Dusername=YOUR_SVN_USER -Dpassword=YOUR_SVN_PASSWORD
+-----------------------------------
+
+  The plugin interactively will ask you the version to release, the Subversion
+  tag to use and the next snapshot version. It is recommended to use the tag:
+  <<tiles-autotag-X.X.X>>.
+
+  See also {{{http://www.apache.org/dev/publishing-maven-artifacts.html}the recommendations of the ASF}}.
+
+* Perform the Release
+
+  To perform the release, i.e. creating and deploying Maven artifacts, use:
+
+-----------------------------------
+mvn release:perform
+-----------------------------------
+
+  It should compile and test everything, build and upload the artifacts and the website for the project.
+
+  Upload the assemblies manually with
+
+-----------------------------------
+cd target/
+svn co https://dist.apache.org/repos/dist/dev/tiles tiles-dist-dev
+mkdir tiles-dist-dev/autotag/${version}
+cp checkout/assembly/target/assembly/* tiles-dist-dev/autotag/${version}/
+svn add tiles-dist-dev/autotag/${version}
+svn ci tiles-dist-dev/autotag/${version}
+-----------------------------------
+
+* Close the staging repository
+
+  Login to {{{https://repository.apache.org} Nexus repository}} using your Apache LDAP credentials.
+  Click on "Staging". Then click on "tiles" in the list of repositories.
+
+  In the panel below you should see an open repository that is linked to your username and ip.
+  Right click on this repository and select "Close".
+  This will close the repository from future deployments and make it available for others to view.
+  If you are staging multiple releases together, skip this step until you have staged everything.
+
+  Enter the name and version of the artifact being released in the "Description" field and then click "Close".
+  This will make it easier to identify it later.
+
+* Verify the staged artifacts
+
+  If you click on your repository, a tree view will appear below.
+  You can then browse the contents to ensure the artifacts are as you expect them.
+  Pay particular attention to the existence of *.asc (signature) files.
+  If the you don't like the content of the repository, right click your repository and choose "Drop".
+  You can then rollback your release and repeat the process.
+
+  Note the repository URL, you will need this in your vote email.
+
+* Verify the uploaded assemblies
+
+  * go to the destination directory on people.apache.org (cd /www/people.apache.org/builds/tiles/autotag/${version})
+
+  * check the presence of the 3 distributions (bin, doc and src), and their signature files (*.asc, *.md5, *sha1).
+
+* Release the JIRA version
+
+  * In JIRA go to the version that you want to release and release it.
+
+  * Create a new version, if it has not been done before.
+
+  * Create the release notes and <<write down the link>> that it uses.
+
+* Send announcement for the test build
+
+  In <<developers mailing list>> send an announcement for the test build:
+
+-----------------------------------
+Subject: [ANNOUNCE] Tiles Autotag ${version} test build available
+
+The test build of Tiles Autotag ${version} is available.
+
+
+No determination as to the quality ('alpha,' 'beta,' or 'GA') of Tiles Autotag
+${version} has been made, and at this time it is simply a "test build". We
+welcome any comments you may have, and will take all feedback into
+account if a quality vote is called for this build.
+
+Release notes:
+
+* ${jira.release.notes}
+
+Distribution:
+
+ * https://dist.apache.org/repos/dist/dev/tiles/autotag/${version}/
+
+Maven 2 staging repository:
+
+ * https://repository.apache.org/content/repositories/tiles-[YOUR REPOSITORY ID]/
+
+A vote regarding the quality of this test build will be initiated
+within the next couple of days.
+-----------------------------------
+
+* Call for a vote
+
+  A few days after the test build announcement, call for a vote in
+  <<developers mailing list>>.
+
+-----------------------------------
+Subject: [VOTE] Tiles Autotag ${version} Release Quality
+
+The Tiles Autotag ${version} test build has been available since ${testBuildDate}.
+
+Release notes:
+
+* ${jira.release.notes}
+
+Distribution:
+
+ * https://dist.apache.org/repos/dist/dev/tiles/autotag/${version}/
+
+Maven 2 staging repository:
+
+ * https://repository.apache.org/content/repositories/tiles-[YOUR REPOSITORY ID]/
+
+If you have had a chance to review the test build, please respond with
+a vote on its quality:
+
+ [ ] Leave at test build
+ [ ] Alpha
+ [ ] Beta
+ [ ] General Availability (GA)
+
+
+Everyone who has tested the build is invited to vote. Votes by PMC
+members are considered binding. A vote passes if there are at least
+three binding +1s and more +1s than -1s.
+-----------------------------------
+
+* Post-vote operations
+
+  After a vote is finished, and it has been decided that is
+  <<at least of alpha quality>>, there is the need of a post-vote process.
+
+** Promote maven staged artifacts
+
+  Once the release is deemed fit for public consumption it can be transfered to a
+  production repository where it will be available to all users.
+
+  Login to {{{https://repository.apache.org}Nexus repository}} again.
+  Click on "Staging" and then on the repository with id "tiles-staging".
+  Find your closed staging repository, right click on it and choose "Release".
+
+  Next click on "Repositories", select the "Releases" repository
+  and validate that your artifacts exist as you expect them.
+
+** Publish distribution artifacts
+
+  * Move assemblies into the Apache {{{http://www.apache.org/dev/release#when-to-archive}dist}} repository:
+
+-------------------------------------------
+svn mv https://dist.apache.org/repos/dist/dev/tiles/autotag/${version} https://dist.apache.org/repos/dist/release/tiles/autotag/
+-------------------------------------------
+
+** Update the site
+
+  * Wait 24 hours to let the mirror sync to the release and then update the
+  site. In particular you have to update the index and the download pages:
+
+------------------------------------------------
+https://svn.apache.org/repos/asf/tiles/site/src/site/xdoc/index.xml
+https://svn.apache.org/repos/asf/tiles/site/src/site/apt/download.apt
+------------------------------------------------
+
+  Build and publish the site:
+
+--------------------------------------
+mvn clean site site:stage
+mvn scm-publish:publish-scm
+# check staging website at target/scmpublish-checkout/index.html
+cd <tiles-site-checkout>/publish/tiles-autotag/
+svn merge ^/tiles/site/staging/tiles-autotag .
+svn ci
+--------------------------------------
+
+** Send announcement
+
+  Finally, send an an announcement to the <<users>> and <<developers mailing
+  list>>:
+
+--------------------------------------
+Subject: [ANNOUNCE] Tiles Autotag ${version} ${quality} released
+
+The Apache Tiles team is pleased to announce the release of Tiles Autotag ${version}
+${quality}.
+
+Available in binary and source distribution.
+
+http://tiles.apache.org/download.html
+
+It is also available in the central Maven repository under Group ID
+"org.apache.tiles".
+
+The 1.x series of the Apache Tiles Autotag framework has a minimum
+requirement of the following specification versions:
+
+* Java Standard Edition (Java SE) 1.8
+
+The release notes are available online at:
+
+* ${jira.release.notes}
+
+Please feel free to test the distribution and post your comments to
+the user list, or, if appropriate, file a ticket with JIRA.
+--------------------------------------
+
+** Delete old releases
+
+  As described in http://www.apache.org/dev/release.html#when-to-archive
+
+
+  <<You have finished!>>
diff --git a/Java-base/tiles-autotag/src/src/site/apt/plugin.apt b/Java-base/tiles-autotag/src/src/site/apt/plugin.apt
new file mode 100644
index 000000000..830a65d25
--- /dev/null
+++ b/Java-base/tiles-autotag/src/src/site/apt/plugin.apt
@@ -0,0 +1,105 @@
+~~ $Id$
+~~
+~~ 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.
+~~
+         -----------
+         Building a tag library for Freemarker, JSP or Velocity
+         -----------
+         
+Building a tag library for Freemarker, JSP or Velocity
+
+  Once you have {{{./taglib.html}created a generic tag library}},
+  Autotag will automatically generate the corresponding library
+  for Freemarker, JSP, or Velocity. You just create a maven project 
+  and include in <<<pom.xml>>>:
+  
+  * The appropriate implementation of tiles-request as a dependency. 
+  For instance to build a JSP taglib:
+
+-----------------
+<dependency>
+  <groupId>org.apache.tiles</groupId>
+  <artifactId>tiles-request-jsp</artifactId>
+  <version>1.0</version>
+</dependency>
+-----------------
+  
+  * Your generic tag library as a dependency. For instance:
+
+-----------------
+<dependency>
+  <groupId>org.example</groupId>
+  <artifactId>my-taglib</artifactId>
+  <version>1.0-SNAPSHOT</version>
+</dependency>
+-----------------
+  
+  * The appropriate configuration of maven-autotag-plugin. For instance:
+  
+-----------------
+<plugin>
+  <groupId>org.apache.tiles.autotag.plugin</groupId>
+  <artifactId>maven-autotag-plugin</artifactId>
+  <version>1.0</version>
+  <executions>
+    <execution>
+      <goals>
+        <goal>generate-jsp</goal>
+      </goals>
+      <configuration>
+        <packageName>org.example.mytaglib.jsp</packageName>
+        <jspRuntime>org.apache.tiles.request.jsp.autotag.JspAutotagRuntime</jspRuntime>
+        <taglibURI>http://example.org/mytaglib</taglibURI>
+      </configuration> 
+    </execution>
+  </executions>
+</plugin>
+-----------------
+
+  No further code is required.
+
+Plugin goals
+
+  one or several of the following goals may be used:
+
+  [generate-jsp] generates the files required for a JSP tag library. It can then be included
+  in a JSP using the configured taglibURI.
+  
+  [generate-freemarker] generates the files required for freemarker user-defined directives.
+  The directives can then be made available to freemarker by adding an instance of the 
+  generated class <<<...FMModelRepository>>> to the freemarker template model.
+  
+  [generate-velocity] generates the files required for velocity user directives. The directives
+  can be made available to Velocity by setting the <<<userdirective>>> property, either manually
+  or by using the generated file <<<META-INF/velocity.properties>>>.
+  
+Plugin configuration
+
+  [packageName] the destination package for the generated classes.
+  
+  [freemarkerRuntime] the runtime implementation of TilesRequest to use for freemarker, for 
+  instance <<<org.apache.tiles.request.freemarker.autotag.FreemarkerAutotagRuntime>>>.
+  
+  [jspRuntime] the runtime implementation of TilesRequest to use for JSP, for 
+  instance <<<org.apache.tiles.request.jsp.autotag.JSPAutotagRuntime>>>.
+  
+  [velocityRuntime] the runtime implementation of TilesRequest to use for velocity, for 
+  instance <<<org.apache.tiles.request.velocity.autotag.VelocityAutotagRuntime>>>.
+  
+  [taglibURI] the URI to use for the JSP taglib.
+  
diff --git a/Java-base/tiles-autotag/src/src/site/apt/taglib.apt b/Java-base/tiles-autotag/src/src/site/apt/taglib.apt
new file mode 100644
index 000000000..88cdfa26a
--- /dev/null
+++ b/Java-base/tiles-autotag/src/src/site/apt/taglib.apt
@@ -0,0 +1,108 @@
+~~ $Id$
+~~
+~~ 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.
+~~
+         -----------
+         Creating a generic tag library with Autotag
+         -----------
+
+Creating a generic tag library
+
+  A generic tag library is a jar file including the classes that implement
+  the tags and a library descriptor <<<META-INF/template-suite.xml>>>, that can be used by
+  Autotag to build specific tag libraries for Freemarker, JSP, and Velocity.
+  
+  The structure of the library descriptor is rather complex; fortunately 
+  Autotag can generate it for you by parsing the sources.
+
+* The tag class
+
+  A tag in the library can be implemented by any java class that fits the following requirements:
+  
+  * The class name ends with <<<Model>>>.
+  
+  * It has a public, non-static, non-abstract method called <<<execute>>>.
+  
+  * The <<<execute>>> method returns <<<void>>>.
+  
+  * The parameters of the <<<execute>>> method are as follows:
+  
+  ** the first parameters may be anything you want; at runtime they will contain the values 
+  assigned to the attributes of the tag in the template. Those parameters may be annotated with
+  <<<org.apache.tiles.autotag.core.runtime.annotation.Parameter>>> in order to specify the name of
+  the attribute, the default value, or to make the parameter mandatory.
+  
+  ** then, one parameter of type <<<org.apache.tiles.request.Request>>>.
+  
+  ** and finally, one optional parameter of type <<<org.apache.tiles.autotag.core.runtime.ModelBody>>>;
+  at runtime it will contain the contents of the tag in the template.
+  
+  For instance:
+
+----------------
+public class MyTagModel {
+
+    public void execute( 
+        @Parameter(required=true) String mandatoryParam, 
+        String optionalParam, 
+        Request request, 
+        ModelBody body) {
+        ...
+    }
+
+}
+----------------
+  
+* Generating the library descriptor
+
+  the library descriptor can be generated using the create-descriptor goal of maven-autotag-plugin.
+  
+-----------------
+<plugin>
+  <groupId>org.apache.tiles.autotag.plugin</groupId>
+  <artifactId>maven-autotag-plugin</artifactId>
+  <version>1.0</version>
+  <executions>
+    <execution>
+      <goals>
+        <goal>create-descriptor</goal>
+      </goals>
+      <configuration>
+        ...
+      </configuration> 
+    </execution>
+  </executions>
+</plugin>
+-----------------
+
+** Configuration reference
+
+  [name] is the name of the tag library (for instance: <<<tiles>>>). It will be used for naming a
+  number of generated files.
+  
+  [documentation] is a documentation that will be included in the library descriptor, and then 
+  later in the appropriate artefacts when generating the taglibs.
+  
+  [includes] specifies what source files should be included, defaults to <<<**/*Model.java>>>.
+  It follows the usual conventions in maven.
+  
+  [excludes] specifies what source files should be included, defaults to nothing.
+  It follows the usual conventions in maven.
+  
+  [outputDirectory] specifies where to put the generated files, defaults to 
+  <<<target/autotag-template-suite>>>.
diff --git a/Java-base/tiles-autotag/src/src/site/site.xml b/Java-base/tiles-autotag/src/src/site/site.xml
new file mode 100644
index 000000000..2b21ad37f
--- /dev/null
+++ b/Java-base/tiles-autotag/src/src/site/site.xml
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+/*
+ * $Id: site.xml 1081442 2011-03-14 16:21:08Z apetrelli $
+ *
+ * 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.
+ */
+-->
+<project name="Apache - Tiles Autotags">
+     <skin>
+        <groupId>org.apache.maven.skins</groupId>
+        <artifactId>maven-fluido-skin</artifactId>
+        <version>1.3.0</version>
+     </skin>
+     <custom>
+        <fluidoSkin>
+        <topBarEnabled>true</topBarEnabled>
+        <sideBarEnabled>false</sideBarEnabled>
+        <searchEnabled>true</searchEnabled>
+        <gitHub>
+            <projectId>apache/tiles-request</projectId>
+            <ribbonOrientation>right</ribbonOrientation>
+            <ribbonColor>darkblue</ribbonColor>
+        </gitHub>
+        </fluidoSkin>
+     </custom>
+    <bannerLeft>
+        <name>Apache Tiles&#8482;</name>
+        <src>http://tiles.apache.org/images/logo.png</src>
+        <href>http://tiles.apache.org</href>
+    </bannerLeft>
+    <bannerRight>
+        <name>Apache Software Foundation</name>
+        <src>https://tiles.apache.org/images/logos/asf_logo_url.svg</src>
+        <href>http://www.apache.org</href>
+    </bannerRight>
+    <body>
+
+        <menu name="Apache Tiles&#8482;">
+            <item
+                   name="Welcome"
+                   href="/index.html"/>
+            <item
+                    name="Tiles 3.0.x"
+                    href="/framework/index.html"/>
+            <item
+                    name="Autotag"
+                    href="/tiles-autotag/index.html"/>
+            <item
+                    name="Request"
+                    href="/tiles-request/index.html"/>
+            <item
+                   name="Download"
+                   href="http://tiles.apache.org/download.html"/>
+        </menu>
+        <menu name="Reference">
+            <item
+                    name="Creating an generic tag library"
+                    href="./taglib.html"/>
+            <item
+                    name="Building a tag library"
+                    href="./plugin.html"/>
+            <item
+                    name="Javadoc"
+                    href="apidocs/index.html"/>
+        </menu>
+
+        <menu name="Developers">
+            <item
+                    name="Building"
+                    href="/dev/building.html"/>
+            <item
+                    name="Snapshots"
+                    href="/dev/snapshots.html"/>
+            <item
+                    name="Release Process"
+                    href="/dev/release.html"/>
+        </menu>
+
+        <menu ref="modules" />
+        <menu ref="reports" />
+
+        <footer>
+            <div class="row span12">
+                Apache Tiles, Tiles, Apache, the Apache feather logo, and the Apache Tiles
+                project logos are trademarks of The Apache Software Foundation.
+            </div>
+        </footer>
+    </body>
+</project>
diff --git a/Java-base/tiles-autotag/src/src/site/xdoc/dev/building.xml b/Java-base/tiles-autotag/src/src/site/xdoc/dev/building.xml
new file mode 100644
index 000000000..f5d19b5ea
--- /dev/null
+++ b/Java-base/tiles-autotag/src/src/site/xdoc/dev/building.xml
@@ -0,0 +1,94 @@
+<?xml version="1.0"?>
+<!--
+/*
+ * $Id$
+ *
+ * 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>Apache Autotag</title>
+    </properties>
+
+    <body>
+        <section name="Building the Autotag project">
+          <subsection name="Prerequisites">
+            <p>For all the next instructions, we assume that you downloaded and
+            installed <a href="http://maven.apache.org/">Maven</a>.</p>
+            <p>To download packages from the source repository, you need to
+            download and install <a href="http://subversion.tigris.org/">
+            Subversion</a>.</p>
+            <p>If you want to build something including JavaDocs (assemblies,
+            sites and JavaDoc report itself) you need to install
+            <a href="http://www.graphviz.org/">GraphViz</a>, otherwise you will
+            notice missing pictures inside JavaDocs pages.</p>
+          </subsection>
+          <subsection name="Building main packages">
+            <p>To build the Autotag project from source you need to:</p>
+            <ul>
+            <li><p><a href="../../download.html">download</a> the source
+            distribution, or checkout the latest version:</p>
+            <p><source>svn co http://svn.apache.org/repos/asf/tiles/framework/trunk/tiles-autotag</source></p></li>
+            <li><p>go into the source directory and type:</p>
+            <p><source>mvn package</source></p></li>
+            </ul>
+            <p>You will find the generated JARs under:</p>
+            <ul>
+            <li>{autotag-dir}/maven-autotag-plugin/target/maven-autotag-plugin-${version}.jar</li>
+            <li>{autotag-dir}/tiles-autotag-core/target/tiles-autotag-core-${version}.jar</li>
+            <li>{autotag-dir}/tiles-autotag-core-runtime/target/tiles-autotag-core-runtime-${version}.jar</li>
+            <li>{autotag-dir}/tiles-autotag-freemarker/target/tiles-autotag-freemarker-${version}.jar</li>
+            <li>{autotag-dir}/tiles-autotag-jsp/target/tiles-autotag-jsp-${version}.jar</li>
+            <li>{autotag-dir}/tiles-autotag-velocity/target/tiles-autotag-velocity-${version}.jar</li>
+            </ul>
+          </subsection>
+        </section>
+        <section name="Building the websites">
+          <p>There are four Tiles websites: the main website and the projects
+          websites (tiles-request, tiles-autotag and framework).</p>
+          <subsection name="Building the main website">
+            <p>To build the main website:</p>
+            <ul>
+            <li><p>checkout the site from the source repository:</p>
+            <p><source>svn co http://svn.apache.org/repos/asf/tiles/site/</source></p></li>
+            <li><p>go into the site directory and type:</p>
+            <p><source>mvn clean site site:stage</source></p></li>
+            </ul>
+            <p>You will find the generated distribution under
+            <code>{tiles-site-dir}/target/staging</code>.</p>
+          </subsection>
+          <subsection name="Building the tiles-autotag website">
+            <p>To build a project's website:</p>
+            <ul>
+            <li><p><a href="../../download.html">download</a> the source
+            distribution, or checkout the latest version:</p>
+            <p><source>svn co http://svn.apache.org/repos/asf/tiles/framework/trunk/tiles-autotag</source></p></li>
+            <li><p>go into the source directory and type:</p>
+            <p><source>mvn clean site site:stage</source></p></li>
+            </ul>
+            <p>You will find the generated website under:</p>
+            <ul>
+            <li>{tiles-autotag-dir}/target/staging</li>
+            </ul>
+          </subsection>
+        </section>
+    </body>
+
+</document>
diff --git a/Java-base/tiles-autotag/src/src/site/xdoc/dev/snapshots.xml b/Java-base/tiles-autotag/src/src/site/xdoc/dev/snapshots.xml
new file mode 100644
index 000000000..359f7cbb2
--- /dev/null
+++ b/Java-base/tiles-autotag/src/src/site/xdoc/dev/snapshots.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0"?>
+<!--
+/*
+ * $Id$
+ *
+ * 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>Apache Tiles</title>
+    </properties>
+
+    <body>
+        <section name="Apache Tiles&#8482;">
+        <subsection name="Snapshots">
+
+        <p>Looking for snapshot builds of the latest version of Tiles?
+           Snapshots are occasionally published to Apache's Maven snapshot
+           repository, which can be accessed with the following configuration:</p>
+
+        <source>
+        <![CDATA[
+          <repository>
+              <id>apache.snapshots</id>
+              <name>Apache Maven Snapshot Repository</name>
+              <url>http://repository.apache.org/snapshots</url>
+          </repository>
+        ]]>
+        </source>
+
+        <p>After configuring the repository, declare a dependency on
+        Tiles Autotag:</p>
+
+        <source><![CDATA[
+          <dependency>
+              <groupId>org.apache.tiles</groupId>
+              <artifactId>tiles-autotag-core-runtime</artifactId>
+              <version>1.0-SNAPSHOT</version>
+          </dependency>
+        ]]>
+        </source>
+        
+        <p>Or the maven plugin:</p>
+        
+        <source><![CDATA[
+          <plugin>
+              <groupId>org.apache.tiles</groupId>
+              <artifactId>maven-autotag-plugin</artifactId>
+              <version>1.0-SNAPSHOT</version>
+              <configuration>
+                  <packageName>...</packageName>
+                  <freemarkerRuntime>...</freemarkerRuntime>
+                  <jspRuntime>...</jspRuntime>
+                  <velocityRuntime>...</velocityRuntime>
+              </configuration>
+          </plugin>
+        ]]>
+        </source>
+
+    </subsection>
+</section>
+</body>
+
+</document>
diff --git a/Java-base/tiles-autotag/src/src/site/xdoc/index.xml b/Java-base/tiles-autotag/src/src/site/xdoc/index.xml
new file mode 100644
index 000000000..8af02b07e
--- /dev/null
+++ b/Java-base/tiles-autotag/src/src/site/xdoc/index.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0"?>
+<!--
+/*
+ * $Id: index.xml 1162124 2011-08-26 14:16:13Z mck $
+ *
+ * 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>Home</title>
+    </properties>
+
+    <body>
+
+        <section name="Apache Autotag project">
+
+            <p>Tiles-3 introduces a feature complete
+                <a href="http://svn.eu.apache.org/repos/asf/tiles/sandbox/trunk/tiles-autotag/" title="Autotag SVN directory">Autotag project</a>,
+                a project that automatically generates tags (or tag-like) artifact from a common template code for a range of templating languages.
+                Today JSP tags, Freemarker directive models and Velocity directives are generated from a common template models.
+            </p>
+            <p>Such template models must have a single public method, with this signature:</p>
+            <p>
+                <span class="Apple-style-span" style="font-family: monospace; white-space: pre;">public void execute(&lt;parameters&gt;, Request request, ModelBody modelBody);</span>&nbsp;
+            </p>
+            <p>The modelBody parameter is optional: if it is not specified, the template model does not have a body.&nbsp;</p>
+            <p>For more features (required fields, default values, a name different to the one specified in the parameter list) a new annotation @Parameter has been created.</p>
+            <p>A Maven 2 (based on 2.2.1) plugin contains four Mojos:</p>
+            <p>&nbsp;</p>
+            <ul>
+                <li>the first mojo (create-descriptor) reads the template models and produces an XML file containing the description of the read models;</li>
+                <li>the others (generate-jsp, generate-freemarker, generate-velocity) produce boilerplate code.</li>
+            </ul>
+                <p>The projects using the latter mojos must include some runtime dependencies.</p>
+                <p>The boilerplate code has been removed and uses the plugin instead: it's a lot of boilerplate, boring code, now generated automatically.
+                </p>
+        </section>
+    </body>
+
+</document>
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core-runtime/pom.xml b/Java-base/tiles-autotag/src/tiles-autotag-core-runtime/pom.xml
new file mode 100644
index 000000000..57f3d0bef
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core-runtime/pom.xml
@@ -0,0 +1,129 @@
+<?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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <artifactId>tiles-autotag</artifactId>
+    <groupId>org.apache.tiles</groupId>
+    <version>1.3-SNAPSHOT</version>
+  </parent>
+  <groupId>org.apache.tiles</groupId>
+  <artifactId>tiles-autotag-core-runtime</artifactId>
+  <version>1.3-SNAPSHOT</version>
+  <name>Autotag - Core runtime</name>
+  <description>Autotag: runtime core classes.</description>
+    <build>
+        <pluginManagement>
+            <plugins>
+                <plugin>
+                    <artifactId>maven-jar-plugin</artifactId>
+                    <configuration>
+                        <archive>
+                            <manifestFile>${tiles.manifestfile}</manifestFile>
+                            <manifest>
+                                <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
+                                <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+                            </manifest>
+                        </archive>
+                    </configuration>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.felix</groupId>
+                    <artifactId>maven-bundle-plugin</artifactId>
+                    <version>2.3.7</version>
+                    <inherited>true</inherited>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <configuration>
+                    <excludeDependencies>true</excludeDependencies>
+                    <manifestLocation>target/osgi</manifestLocation>
+                    <instructions>
+                        <_nouses>true</_nouses>
+                        <Bundle-SymbolicName>${tiles.osgi.symbolicName}</Bundle-SymbolicName>
+                        <Export-Package>${tiles.osgi.export}</Export-Package>
+                        <Private-Package>${tiles.osgi.private}</Private-Package>
+                        <Import-Package>${tiles.osgi.import}</Import-Package>
+                        <DynamicImport-Package>${tiles.osgi.dynamicImport}</DynamicImport-Package>
+                        <Bundle-DocURL>${project.url}</Bundle-DocURL>
+                        <Specification-Title>${project.name}</Specification-Title>
+                        <Specification-Version>${project.version}</Specification-Version>
+                        <Specification-Vendor>${project.organization.name}</Specification-Vendor>
+                        <Implementation-Title>${project.name}</Implementation-Title>
+                        <Implementation-Version>${project.version}</Implementation-Version>
+                        <Implementation-Vendor>${project.organization.name}</Implementation-Vendor>
+                        <Implementation-Vendor-Id>org.apache</Implementation-Vendor-Id>
+                    </instructions>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>bundle-manifest</id>
+                        <phase>process-classes</phase>
+                        <goals>
+                            <goal>manifest</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-release-plugin</artifactId>
+                <configuration>
+                    <releaseProfiles>apache-release</releaseProfiles><!-- xxx tiles still uses "release" instead of "apache-release" -->
+                    <goals>deploy site-deploy</goals>
+                </configuration>
+            </plugin>
+        </plugins>
+
+        <defaultGoal>install</defaultGoal>
+    </build>
+
+    <properties>
+        <tiles.osgi.symbolicName>org.apache.${project.artifactId}</tiles.osgi.symbolicName>
+        <tiles.osgi.export>org.apache.tiles.*;version=${project.version}</tiles.osgi.export>
+        <tiles.osgi.import>*</tiles.osgi.import>
+        <tiles.osgi.dynamicImport />
+        <tiles.osgi.private />
+        <tiles.manifestfile>target/osgi/MANIFEST.MF</tiles.manifestfile>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+
+        <!-- decrease this whenever possible -->
+        <checkstyle.maxAllowedViolations>7</checkstyle.maxAllowedViolations>
+    </properties>
+
+  <dependencies>
+      <dependency>
+      	<groupId>junit</groupId>
+      	<artifactId>junit</artifactId>
+      	<scope>test</scope>
+      </dependency>
+      <dependency>
+      	<groupId>org.easymock</groupId>
+      	<artifactId>easymock</artifactId>
+      	<scope>test</scope>
+      </dependency>
+  </dependencies>
+</project>
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core-runtime/src/main/java/org/apache/tiles/autotag/core/runtime/AbstractModelBody.java b/Java-base/tiles-autotag/src/tiles-autotag-core-runtime/src/main/java/org/apache/tiles/autotag/core/runtime/AbstractModelBody.java
new file mode 100644
index 000000000..4a17fa986
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core-runtime/src/main/java/org/apache/tiles/autotag/core/runtime/AbstractModelBody.java
@@ -0,0 +1,87 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.core.runtime;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.regex.Pattern;
+
+import org.apache.tiles.autotag.core.runtime.util.NullWriter;
+
+/**
+ * Base class for the abstraction of the body.
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class AbstractModelBody implements ModelBody {
+
+    // precompiled the pattern to avoid compiling on every method call
+    private static final Pattern PATTERN = Pattern.compile("^\\s*|\\s*$");
+
+    /**
+     * The default writer to use.
+     */
+    private Writer defaultWriter;
+
+    /**
+     * Constructor.
+     *
+     * @param defaultWriter The default writer to use.
+     */
+    public AbstractModelBody(Writer defaultWriter) {
+        this.defaultWriter = defaultWriter;
+    }
+
+    @Override
+    public void evaluate() throws IOException {
+        evaluate(defaultWriter);
+    }
+
+    @Override
+    public String evaluateAsString() throws IOException {
+        StringWriter writer = new StringWriter();
+        try {
+            evaluate(writer);
+        } finally {
+            writer.close();
+        }
+        String body = writer.toString();
+        if (body != null) {
+            body = PATTERN.matcher(body).replaceAll("");
+            if (body.length() <= 0) {
+                body = null;
+            }
+        }
+        return body;
+    }
+
+    @Override
+    public void evaluateWithoutWriting() throws IOException {
+        NullWriter writer = new NullWriter();
+        try {
+            evaluate(writer);
+        } finally {
+            writer.close();
+        }
+    }
+
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core-runtime/src/main/java/org/apache/tiles/autotag/core/runtime/AutotagRuntime.java b/Java-base/tiles-autotag/src/tiles-autotag-core-runtime/src/main/java/org/apache/tiles/autotag/core/runtime/AutotagRuntime.java
new file mode 100644
index 000000000..4d5c818d7
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core-runtime/src/main/java/org/apache/tiles/autotag/core/runtime/AutotagRuntime.java
@@ -0,0 +1,51 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.core.runtime;
+
+/**
+ * Builder interface for creating requests.
+ * The implementations are expected to provide a default constructor,
+ * and to implement another interface that can be used to provide the
+ * parameters needed to build the actual request object.
+ */
+public interface AutotagRuntime<R> {
+    /**
+     * Creates a new Request instance.
+     *
+     * @return The Request.
+     */
+    R createRequest();
+
+    /**
+     * Creates a new ModelBody instance to match the request.
+     *
+     * @return The ModelBody.
+     */
+    ModelBody createModelBody();
+
+    /**
+     * Extracts a parameter from the tag.
+     * @param name The name of the parameter.
+     * @param defaultValue The default value if none is specified.
+     * @return The value of the parameter.
+     */
+    <T> T getParameter(String name, Class<T> type, T defaultValue);
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core-runtime/src/main/java/org/apache/tiles/autotag/core/runtime/ModelBody.java b/Java-base/tiles-autotag/src/tiles-autotag-core-runtime/src/main/java/org/apache/tiles/autotag/core/runtime/ModelBody.java
new file mode 100644
index 000000000..81178eedd
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core-runtime/src/main/java/org/apache/tiles/autotag/core/runtime/ModelBody.java
@@ -0,0 +1,62 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.core.runtime;
+
+import java.io.IOException;
+import java.io.Writer;
+
+/**
+ * Abstracts a tag/directive body.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface ModelBody {
+
+    /**
+     * Evaluates a body and returns it as a string.
+     *
+     * @return The body, as a string.
+     * @throws IOException If something goes wrong.
+     */
+    String evaluateAsString() throws IOException;
+
+    /**
+     * Evaluates a body, but discards result.
+     *
+     * @throws IOException If something goes wrong.
+     */
+    void evaluateWithoutWriting() throws IOException;
+
+    /**
+     * Evaluates the body and writes in the default writer.
+     *
+     * @throws IOException If something goes wrong.
+     */
+    void evaluate() throws IOException;
+
+    /**
+     * Evaluates the body and writes the result in the writer.
+     *
+     * @param writer The writer to write the result into.
+     * @throws IOException If something goes wrong.
+     */
+    void evaluate(Writer writer) throws IOException;
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core-runtime/src/main/java/org/apache/tiles/autotag/core/runtime/annotation/Parameter.java b/Java-base/tiles-autotag/src/tiles-autotag-core-runtime/src/main/java/org/apache/tiles/autotag/core/runtime/annotation/Parameter.java
new file mode 100644
index 000000000..6f9c99b8c
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core-runtime/src/main/java/org/apache/tiles/autotag/core/runtime/annotation/Parameter.java
@@ -0,0 +1,56 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.core.runtime.annotation;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Specifies behaviour for a parameter of the "execute" method of a template class.
+ *
+ * @version $Rev$ $Date$
+ */
+@Retention(RetentionPolicy.SOURCE)
+@Target(ElementType.PARAMETER)
+public @interface Parameter {
+
+    /**
+     * Indicates to use the parameter name itself for the exported name.
+     */
+    String SAME_NAME = "USE THE SAME NAME";
+
+    /**
+     * Returns the name of the exported property name.
+     */
+    String name() default SAME_NAME;
+
+    /**
+     * Indicates that this parameter is required.
+     */
+    boolean required() default false;
+
+    /**
+     * Indicates the default value, as it will be written in Java code.
+     */
+    String defaultValue() default "null";
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core-runtime/src/main/java/org/apache/tiles/autotag/core/runtime/annotation/package-info.java b/Java-base/tiles-autotag/src/tiles-autotag-core-runtime/src/main/java/org/apache/tiles/autotag/core/runtime/annotation/package-info.java
new file mode 100644
index 000000000..261b48ebd
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core-runtime/src/main/java/org/apache/tiles/autotag/core/runtime/annotation/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * Annotations to be used in template classes.
+ */
+package org.apache.tiles.autotag.core.runtime.annotation;
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core-runtime/src/main/java/org/apache/tiles/autotag/core/runtime/package-info.java b/Java-base/tiles-autotag/src/tiles-autotag-core-runtime/src/main/java/org/apache/tiles/autotag/core/runtime/package-info.java
new file mode 100644
index 000000000..1e8324a66
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core-runtime/src/main/java/org/apache/tiles/autotag/core/runtime/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * Runtime part for all Autotag generated code.
+ */
+package org.apache.tiles.autotag.core.runtime;
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core-runtime/src/main/java/org/apache/tiles/autotag/core/runtime/util/NullWriter.java b/Java-base/tiles-autotag/src/tiles-autotag-core-runtime/src/main/java/org/apache/tiles/autotag/core/runtime/util/NullWriter.java
new file mode 100644
index 000000000..6a66fb3a3
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core-runtime/src/main/java/org/apache/tiles/autotag/core/runtime/util/NullWriter.java
@@ -0,0 +1,50 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.autotag.core.runtime.util;
+
+import java.io.Writer;
+
+/**
+ * A writer that does not write anything.
+ *
+ * @version $Rev$ $Date$
+ */
+public class NullWriter extends Writer {
+
+    /** {@inheritDoc} */
+    @Override
+    public void close() {
+        // Does nothing
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void flush() {
+        // Does nothing
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void write(char[] cbuf, int off, int len) {
+        // Does nothing
+    }
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core-runtime/src/main/java/org/apache/tiles/autotag/core/runtime/util/package-info.java b/Java-base/tiles-autotag/src/tiles-autotag-core-runtime/src/main/java/org/apache/tiles/autotag/core/runtime/util/package-info.java
new file mode 100644
index 000000000..7f2e35629
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core-runtime/src/main/java/org/apache/tiles/autotag/core/runtime/util/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * Utilities for Autotag core runtime.
+ */
+package org.apache.tiles.autotag.core.runtime.util;
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core-runtime/src/site/site.xml b/Java-base/tiles-autotag/src/tiles-autotag-core-runtime/src/site/site.xml
new file mode 100644
index 000000000..0a7d00df4
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core-runtime/src/site/site.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+/*
+ * $Id: site.xml 1081442 2011-03-14 16:21:08Z apetrelli $
+ *
+ * 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.
+ */
+-->
+<project name="Apache - Tiles Autotags">
+    <bannerLeft>
+        <name>Apache Software Foundation</name>
+        <src>http://www.apache.org/images/asf-logo.gif</src>
+        <href>http://www.apache.org</href>
+    </bannerLeft>
+    <bannerRight>
+        <name>Apache Tiles&#8482;</name>
+        <src>http://tiles.apache.org/images/logo.png</src>
+        <href>http://tiles.apache.org</href>
+    </bannerRight>
+    <body>
+
+        <links>
+            <item name="Apache" href="http://www.apache.org" />
+            <item name="Tiles" href="http://tiles.apache.org" />
+        </links>
+
+
+        <menu name="Apache Tiles&#8482;">
+            <item
+                   name="Tiles Home"
+                   href="../../index.html"/>
+            <item
+                   name="Tiles Autotag"
+                   href="../index.html"/>
+        </menu>
+
+        <menu ref="modules" />
+        <menu ref="reports" />
+
+    </body>
+</project>
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core-runtime/src/test/java/org/apache/tiles/autotag/core/runtime/AbstractModelBodyTest.java b/Java-base/tiles-autotag/src/tiles-autotag-core-runtime/src/test/java/org/apache/tiles/autotag/core/runtime/AbstractModelBodyTest.java
new file mode 100644
index 000000000..c37ef45c6
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core-runtime/src/test/java/org/apache/tiles/autotag/core/runtime/AbstractModelBodyTest.java
@@ -0,0 +1,154 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.core.runtime;
+
+import static org.easymock.EasyMock.*;
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+
+import org.apache.tiles.autotag.core.runtime.util.NullWriter;
+import org.junit.Test;
+
+/**
+ * Tests {@link AbstractModelBody}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class AbstractModelBodyTest {
+
+    /**
+     * Test method for {@link org.apache.tiles.autotag.core.runtime.AbstractModelBody#evaluate()}.
+     * @throws IOException If something goes wrong.
+     */
+    @Test
+    public void testEvaluate() throws IOException {
+        Writer writer = createMock(Writer.class);
+        AbstractModelBody modelBody = createMockBuilder(AbstractModelBody.class).withConstructor(writer).createMock();
+
+        modelBody.evaluate(writer);
+
+        replay(writer, modelBody);
+        modelBody.evaluate();
+        verify(writer, modelBody);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.autotag.core.runtime.AbstractModelBody#evaluateAsString()}.
+     * @throws IOException If something goes wrong.
+     */
+    @Test
+    public void testEvaluateAsString() throws IOException {
+        AbstractModelBody modelBody = new MockModelBody(null, "return me");
+        assertEquals("return me", modelBody.evaluateAsString());
+
+        modelBody = new MockModelBody(null, "\n   \n");
+        assertNull(modelBody.evaluateAsString());
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.autotag.core.runtime.AbstractModelBody#evaluateAsString()}.
+     * @throws IOException If something goes wrong.
+     */
+    @Test(expected = IOException.class)
+    public void testEvaluateAsStringException() throws IOException {
+        Writer writer = createMock(Writer.class);
+        AbstractModelBody modelBody = createMockBuilder(AbstractModelBody.class).withConstructor(writer).createMock();
+
+        modelBody.evaluate(isA(StringWriter.class));
+        expectLastCall().andThrow(new IOException());
+
+        replay(writer, modelBody);
+        try {
+            modelBody.evaluateAsString();
+        } finally {
+            verify(writer, modelBody);
+        }
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.autotag.core.runtime.AbstractModelBody#evaluateWithoutWriting()}.
+     * @throws IOException If something goes wrong.
+     */
+    @Test
+    public void testEvaluateWithoutWriting() throws IOException {
+        Writer writer = createMock(Writer.class);
+        AbstractModelBody modelBody = createMockBuilder(AbstractModelBody.class).withConstructor(writer).createMock();
+
+        modelBody.evaluate(isA(NullWriter.class));
+
+        replay(writer, modelBody);
+        modelBody.evaluateWithoutWriting();
+        verify(writer, modelBody);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.autotag.core.runtime.AbstractModelBody#evaluateWithoutWriting()}.
+     * @throws IOException If something goes wrong.
+     */
+    @Test(expected = IOException.class)
+    public void testEvaluateWithoutWritingException() throws IOException {
+        Writer writer = createMock(Writer.class);
+        AbstractModelBody modelBody = createMockBuilder(AbstractModelBody.class).withConstructor(writer).createMock();
+
+        modelBody.evaluate(isA(NullWriter.class));
+        expectLastCall().andThrow(new IOException());
+
+        replay(writer, modelBody);
+        try {
+            modelBody.evaluateWithoutWriting();
+        } finally {
+            verify(writer, modelBody);
+        }
+    }
+
+    /**
+     * A mock model body.
+     *
+     * @version $Rev$ $Date$
+     */
+    public static class MockModelBody extends AbstractModelBody {
+
+        /**
+         * The result to return.
+         */
+        private String toReturn;
+
+        /**
+         * Constructor.
+         *
+         * @param defaultWriter The default writer.
+         * @param toReturn The result to return.
+         */
+        public MockModelBody(Writer defaultWriter, String toReturn) {
+            super(defaultWriter);
+            this.toReturn = toReturn;
+        }
+
+        @Override
+        public void evaluate(Writer writer) throws IOException {
+            writer.write(toReturn);
+        }
+
+    }
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core-runtime/src/test/java/org/apache/tiles/autotag/core/runtime/util/NullWriterTest.java b/Java-base/tiles-autotag/src/tiles-autotag-core-runtime/src/test/java/org/apache/tiles/autotag/core/runtime/util/NullWriterTest.java
new file mode 100644
index 000000000..f8a2ba2eb
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core-runtime/src/test/java/org/apache/tiles/autotag/core/runtime/util/NullWriterTest.java
@@ -0,0 +1,74 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.core.runtime.util;
+
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests {@link NullWriter}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class NullWriterTest {
+
+    /**
+     * A dummy size.
+     */
+    private static final int DUMMY_SIZE = 15;
+    /**
+     * The object to test.
+     */
+    private NullWriter writer;
+
+    /**
+     * Sets up the test.
+     */
+    @Before
+    public void setUp() {
+        writer = new NullWriter();
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.autotag.core.runtime.util.NullWriter#write(char[], int, int)}.
+     */
+    @Test
+    public void testWriteCharArrayIntInt() {
+        writer.write("Hello there".toCharArray(), 0, DUMMY_SIZE);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.autotag.core.runtime.util.NullWriter#flush()}.
+     */
+    @Test
+    public void testFlush() {
+        writer.flush();
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.autotag.core.runtime.util.NullWriter#close()}.
+     */
+    @Test
+    public void testClose() {
+        writer.close();
+    }
+
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core/pom.xml b/Java-base/tiles-autotag/src/tiles-autotag-core/pom.xml
new file mode 100644
index 000000000..f198f0a39
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core/pom.xml
@@ -0,0 +1,82 @@
+<?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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<artifactId>tiles-autotag</artifactId>
+		<groupId>org.apache.tiles</groupId>
+		<version>1.3-SNAPSHOT</version>
+	</parent>
+	<groupId>org.apache.tiles</groupId>
+	<artifactId>tiles-autotag-core</artifactId>
+	<version>1.3-SNAPSHOT</version>
+	<name>Autotag - Core</name>
+	<description>Core classes for Autotag.</description>
+	<build>
+		<resources>
+		</resources>
+		<testResources>
+			<testResource>
+				<directory>src/test/java</directory>
+				<includes>
+					<include>org/apache/tiles/autotag/core/internal/*.java</include>
+				</includes>
+			</testResource>
+			<testResource>
+				<directory>src/test/resources</directory>
+			</testResource>
+		</testResources>
+	</build>
+    <properties>
+        <!-- decrease this whenever possible -->
+        <checkstyle.maxAllowedViolations>35</checkstyle.maxAllowedViolations>
+    </properties>
+	<dependencies>
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>com.thoughtworks.qdox</groupId>
+			<artifactId>qdox</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.easymock</groupId>
+			<artifactId>easymock</artifactId>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.tiles</groupId>
+			<artifactId>tiles-autotag-core-runtime</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.velocity</groupId>
+			<artifactId>velocity</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>commons-io</groupId>
+			<artifactId>commons-io</artifactId>
+			<scope>test</scope>
+		</dependency>
+	</dependencies>
+</project>
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/core/AutotagRuntimeException.java b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/core/AutotagRuntimeException.java
new file mode 100644
index 000000000..908c965f9
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/core/AutotagRuntimeException.java
@@ -0,0 +1,66 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.core;
+
+/**
+ * Generic exception for Autotag.
+ *
+ * @version $Rev$ $Date$
+ */
+public class AutotagRuntimeException extends RuntimeException {
+
+	private static final long serialVersionUID = -7265964601637841559L;
+
+	/**
+     * Constructor.
+     */
+    public AutotagRuntimeException() {
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param message The message of the exception.
+     */
+    public AutotagRuntimeException(String message) {
+        super(message);
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param cause The cause.
+     */
+    public AutotagRuntimeException(Throwable cause) {
+        super(cause);
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param message The message of the exception.
+     * @param cause The cause.
+     */
+    public AutotagRuntimeException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/core/ClassParseException.java b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/core/ClassParseException.java
new file mode 100644
index 000000000..8c51dbebb
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/core/ClassParseException.java
@@ -0,0 +1,66 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.core;
+
+/**
+ * Thrown if there is a problem when parsing a class source.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ClassParseException extends AutotagRuntimeException {
+
+	private static final long serialVersionUID = -8579521283073016196L;
+
+	/**
+     * Constructor.
+     */
+    public ClassParseException() {
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param message The message of the exception.
+     */
+    public ClassParseException(String message) {
+        super(message);
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param cause The cause.
+     */
+    public ClassParseException(Throwable cause) {
+        super(cause);
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param message The message of the exception.
+     * @param cause The cause.
+     */
+    public ClassParseException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/core/DirectoryOutputLocator.java b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/core/DirectoryOutputLocator.java
new file mode 100644
index 000000000..4871f6d00
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/core/DirectoryOutputLocator.java
@@ -0,0 +1,59 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.core;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Outputs the files in the test directory.
+ */
+public class DirectoryOutputLocator implements OutputLocator {
+
+	private File directory;
+	private long sourceLastModified;
+
+	public DirectoryOutputLocator(File directory) {
+		this.directory = directory;
+		this.sourceLastModified = System.currentTimeMillis();
+	}
+
+	public DirectoryOutputLocator(File directory, long sourceLastModified) {
+		this.directory = directory;
+		this.sourceLastModified = sourceLastModified;
+	}
+
+	@Override
+	public OutputStream getOutputStream(String resourcePath) throws IOException {
+		File file = new File(directory, resourcePath);
+		file.getParentFile().mkdirs();
+		return new FileOutputStream(file);
+	}
+
+	@Override
+	public boolean isUptodate(String resourcePath) {
+		File file = new File(directory, resourcePath);
+		return file.exists() && file.lastModified() > sourceLastModified;
+	}
+
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/core/OutputLocator.java b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/core/OutputLocator.java
new file mode 100644
index 000000000..2608e1fbc
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/core/OutputLocator.java
@@ -0,0 +1,43 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.core;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * Decouples the autotag generator from the actual location of the files.
+ */
+public interface OutputLocator {
+	/**
+	 * Returns a writer for the file at this path.
+	 * @param resourcePath the path of the file to write
+	 * @return a Writer for the file.
+	 */
+	OutputStream getOutputStream(String resourcePath) throws IOException;
+	
+	/**
+	 * Checks if the output is up to date.
+	 * @param resourcePath the path of the file to write.
+	 * @return true if the output doesn't need to be generated again.
+	 */
+	boolean isUptodate(String resourcePath);
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/core/QDoxTemplateSuiteFactory.java b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/core/QDoxTemplateSuiteFactory.java
new file mode 100644
index 000000000..8a55a6f57
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/core/QDoxTemplateSuiteFactory.java
@@ -0,0 +1,274 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.core;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tiles.autotag.core.runtime.ModelBody;
+import org.apache.tiles.autotag.core.runtime.annotation.Parameter;
+import org.apache.tiles.autotag.model.TemplateClass;
+import org.apache.tiles.autotag.model.TemplateMethod;
+import org.apache.tiles.autotag.model.TemplateParameter;
+import org.apache.tiles.autotag.model.TemplateSuite;
+import org.apache.tiles.autotag.model.TemplateSuiteFactory;
+
+import com.thoughtworks.qdox.JavaDocBuilder;
+import com.thoughtworks.qdox.model.Annotation;
+import com.thoughtworks.qdox.model.DocletTag;
+import com.thoughtworks.qdox.model.JavaClass;
+import com.thoughtworks.qdox.model.JavaMethod;
+import com.thoughtworks.qdox.model.JavaParameter;
+import com.thoughtworks.qdox.model.Type;
+
+/**
+ * Creates a template suite using QDox.
+ *
+ * @version $Rev$ $Date$
+ */
+public class QDoxTemplateSuiteFactory implements TemplateSuiteFactory {
+
+    /**
+     * The suffix of parsed classes.
+     */
+    private static final String TEMPLATE_SUFFIX = "Model";
+
+    /**
+     * The Javadoc builder.
+     */
+    private JavaDocBuilder builder;
+
+    /**
+     * The name of the suite.
+     */
+    private String suiteName;
+
+    /**
+     * The documentation of the suite.
+     */
+    private String suiteDocumentation;
+
+    /**
+     * The request class the suite.
+     */
+    private String requestClass;
+
+    /**
+     * Constructor.
+     *
+     * @param sourceFiles All the source files to parse.
+     */
+    public QDoxTemplateSuiteFactory(File... sourceFiles) {
+        builder = new JavaDocBuilder();
+        try {
+            for (File file : sourceFiles) {
+                builder.addSource(file);
+            }
+        } catch (IOException e) {
+            throw new ClassParseException(
+                    "I/O Exception when adding source files", e);
+        }
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param urls All the URLs of source files to parse.
+     */
+    public QDoxTemplateSuiteFactory(URL... urls) {
+        builder = new JavaDocBuilder();
+        try {
+            for (URL url : urls) {
+                builder.addSource(url);
+            }
+        } catch (IOException e) {
+            throw new ClassParseException(
+                    "I/O Exception when adding source files", e);
+        }
+    }
+
+    /**
+     * Sets the suite name to assign to the created suite.
+     *
+     * @param suiteName The suite name.
+     */
+    public void setSuiteName(String suiteName) {
+        this.suiteName = suiteName;
+    }
+
+    /**
+     * Sets the suite documentation to assign to the suite.
+     *
+     * @param suiteDocumentation The suite documentation.
+     */
+    public void setSuiteDocumentation(String suiteDocumentation) {
+        this.suiteDocumentation = suiteDocumentation;
+    }
+
+    /**
+     * Sets the request class used by the suite.
+     *
+     * @param requestClass The request class name.
+     */
+    public void setRequestClass(String requestClass) {
+        this.requestClass = requestClass;
+    }
+
+    @Override
+    public TemplateSuite createTemplateSuite() {
+        List<TemplateClass> classes = new ArrayList<TemplateClass>();
+        for (JavaClass clazz : builder.getClasses()) {
+            String tagClassPrefix = getTagClassPrefix(clazz);
+            if (tagClassPrefix != null) {
+                String tagName = tagClassPrefix.substring(0, 1).toLowerCase()
+                        + tagClassPrefix.substring(1);
+                TemplateMethod executeMethod = null;
+                for (JavaMethod method : clazz.getMethods()) {
+                    if (isFeasible(method)) {
+                        executeMethod = createMethod(method);
+                    }
+                }
+                if (executeMethod != null) {
+                    TemplateClass templateClass = new TemplateClass(clazz
+                            .getFullyQualifiedName(), tagName, tagClassPrefix,
+                            executeMethod);
+                    templateClass.setDocumentation(clazz.getComment());
+                    classes.add(templateClass);
+                }
+            }
+        }
+        return new TemplateSuite(suiteName, suiteDocumentation, classes);
+    }
+
+    /**
+     * Computes the tag class prefix.
+     *
+     * @param clazz The parsed class.
+     * @return The tag class prefix.
+     */
+    private String getTagClassPrefix(JavaClass clazz) {
+        String tagName;
+        String simpleClassName = clazz.getName();
+        if (simpleClassName.endsWith(TEMPLATE_SUFFIX)
+                && simpleClassName.length() > TEMPLATE_SUFFIX.length()) {
+            tagName = simpleClassName.substring(0, 1).toUpperCase()
+                    + simpleClassName.substring(1, simpleClassName.length()
+                            - TEMPLATE_SUFFIX.length());
+        } else {
+            tagName = null;
+        }
+        return tagName;
+    }
+
+    /**
+     * Creates a template method descriptor from a parsed method.
+     *
+     * @param method The parsed method.
+     * @return The template method descriptor.
+     */
+    private TemplateMethod createMethod(JavaMethod method) {
+        List<TemplateParameter> params = new ArrayList<TemplateParameter>();
+        for (JavaParameter parameter : method.getParameters()) {
+            String exportedName = parameter.getName();
+            boolean required = false;
+            String defaultValue = null;
+            Annotation[] annotations = parameter.getAnnotations();
+            if (annotations != null && annotations.length > 0) {
+                boolean found = false;
+                for (int i = 0; i < annotations.length && !found; i++) {
+                    if (Parameter.class.getName().equals(annotations[i].getType().getFullyQualifiedName())) {
+                        found = true;
+                        String candidateName = (String) annotations[i].getNamedParameter("name");
+                        if (candidateName != null && candidateName.length() > 2) {
+                            exportedName = candidateName.substring(1, candidateName.length() - 1);
+                        }
+                        required = "true".equals(annotations[i].getNamedParameter("required"));
+                        candidateName = (String) annotations[i].getNamedParameter("defaultValue");
+                        if (candidateName != null && candidateName.length() > 2) {
+                            defaultValue = candidateName.substring(1, candidateName.length() - 1);
+                        }
+                    }
+                }
+            }
+            String parameterType = parameter.getType()
+                    .getFullyQualifiedName();
+            TemplateParameter templateParameter = new TemplateParameter(
+                    parameter.getName(), exportedName, parameterType, defaultValue, required,
+                    requestClass.equals(parameterType));
+            params.add(templateParameter);
+        }
+        TemplateMethod templateMethod = new TemplateMethod(method.getName(),
+                params);
+        templateMethod.setDocumentation(method.getComment());
+        DocletTag[] tags = method.getTagsByName("param");
+        for (DocletTag tag : tags) {
+            String[] tagParams = tag.getParameters();
+            if (tagParams.length > 0) {
+                TemplateParameter templateParameter = templateMethod
+                        .getParameterByName(tagParams[0]);
+                if (templateParameter != null) {
+                    String tagValue = tag.getValue();
+                    int pos = tagValue.indexOf(" ");
+                    templateParameter.setDocumentation(tagValue.substring(pos)
+                            .trim());
+                }
+            }
+        }
+        return templateMethod;
+    }
+
+    /**
+     * Verifies if the method can be used as an "execute" method.
+     *
+     * @param method The parsed method.
+     * @return <code>true</code> if it is an execute method.
+     */
+    private boolean isFeasible(JavaMethod method) {
+        Type returns = method.getReturns();
+        if ("execute".equals(method.getName()) && returns != null
+                && "void".equals(returns.getFullyQualifiedName())
+                && method.isPublic() && !method.isStatic()
+                && !method.isAbstract() && !method.isConstructor()) {
+            JavaParameter[] params = method.getParameters();
+            if (params.length > 0) {
+                JavaParameter param = params[params.length - 1];
+                if (requestClass.equals(
+                        param.getType().getFullyQualifiedName())) {
+                    return true;
+                }
+            }
+            if (params.length >= 2) {
+                JavaParameter param1 = params[params.length - 2];
+                JavaParameter param2 = params[params.length - 1];
+                if (requestClass.equals(
+                        param1.getType().getFullyQualifiedName())
+                        && ModelBody.class.getName().equals(
+                                param2.getType().getFullyQualifiedName())) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/core/package-info.java b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/core/package-info.java
new file mode 100644
index 000000000..d7ed8d7b0
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/core/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * The Autotag core parsing code.
+ */
+package org.apache.tiles.autotag.core;
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/generate/AbstractTemplateClassGenerator.java b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/generate/AbstractTemplateClassGenerator.java
new file mode 100644
index 000000000..90ca3a717
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/generate/AbstractTemplateClassGenerator.java
@@ -0,0 +1,146 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.generate;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.util.Map;
+
+import org.apache.tiles.autotag.core.AutotagRuntimeException;
+import org.apache.tiles.autotag.core.OutputLocator;
+import org.apache.tiles.autotag.model.TemplateClass;
+import org.apache.tiles.autotag.model.TemplateSuite;
+import org.apache.tiles.autotag.tool.StringTool;
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
+import org.apache.velocity.exception.ParseErrorException;
+import org.apache.velocity.exception.ResourceNotFoundException;
+
+/**
+ * A base template class generator.
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class AbstractTemplateClassGenerator implements
+        TemplateClassGenerator {
+
+    /**
+     * The Velocity engine to use.
+     */
+    private VelocityEngine velocityEngine;
+
+    /**
+     * Constructor.
+     *
+     * @param velocityEngine The Velocity engine.
+     */
+    public AbstractTemplateClassGenerator(VelocityEngine velocityEngine) {
+        this.velocityEngine = velocityEngine;
+    }
+
+    @Override
+    public void generate(OutputLocator outputLocator, String packageName,
+            TemplateSuite suite, TemplateClass clazz, Map<String, String> parameters,
+            String runtimeClass, String requestClass) {
+        String filePath =
+        		getDirectoryName(packageName, suite, clazz, parameters, runtimeClass, requestClass)
+                + File.separator
+                + getFilename(packageName, suite, clazz, parameters, runtimeClass, requestClass);
+		if (!outputLocator.isUptodate(filePath)) {
+	        VelocityContext context = new VelocityContext();
+	        context.put("packageName", packageName);
+	        context.put("suite", suite);
+	        context.put("clazz", clazz);
+	        context.put("stringTool", new StringTool());
+	        context.put("parameters", parameters);
+	        context.put("runtimeClass", runtimeClass);
+	        context.put("requestClass", requestClass);
+	        try {
+	            Template template = velocityEngine.getTemplate(getTemplatePath(
+	                    packageName, suite, clazz, parameters, runtimeClass, requestClass));
+	            Writer writer = new OutputStreamWriter(outputLocator.getOutputStream(filePath));
+	            try {
+	                template.merge(context, writer);
+	            } finally {
+	                writer.close();
+	            }
+	        } catch (ResourceNotFoundException e) {
+	            throw new AutotagRuntimeException("Cannot find template resource",
+	                    e);
+	        } catch (ParseErrorException e) {
+	            throw new AutotagRuntimeException(
+	                    "The template resource is not parseable", e);
+	        } catch (IOException e) {
+	            throw new AutotagRuntimeException(
+	                    "I/O Exception when generating file", e);
+	        } catch (RuntimeException e) {
+	            throw e;
+	        } catch (Exception e) {
+	            throw new AutotagRuntimeException(
+	                    "Another generic exception while parsing the template resource",
+	                    e);
+	        }
+		}
+    }
+
+    /**
+     * Calculates and returns the template path.
+     *
+     * @param packageName The name of the package.
+     * @param suite The template suite.
+     * @param clazz The template class.
+     * @param parameters The map of parameters.
+     * @return The template path.
+     */
+    protected abstract String getTemplatePath(
+            String packageName, TemplateSuite suite, TemplateClass clazz, Map<String, String> parameters,
+            String runtimeClass, String requestClass);
+
+    /**
+     * Calculates and returns the filename of the generated file.
+     *
+     * @param packageName The name of the package.
+     * @param suite The template suite.
+     * @param clazz The template class.
+     * @param parameters The map of parameters.
+     * @return The template path.
+     */
+    protected abstract String getFilename(String packageName,
+            TemplateSuite suite, TemplateClass clazz, Map<String, String> parameters, String runtimeClass,
+            String requestClass);
+
+    /**
+     * Calculates and returns the directory where the file will be written..
+     *
+     * @param packageName The name of the package.
+     * @param suite The template suite.
+     * @param clazz The template class.
+     * @param parameters The map of parameters.
+     * @return The template path.
+     */
+    protected abstract String getDirectoryName(
+            String packageName, TemplateSuite suite, TemplateClass clazz, Map<String, String> parameters,
+            String runtimeClass, String requestClass);
+
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/generate/AbstractTemplateSuiteGenerator.java b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/generate/AbstractTemplateSuiteGenerator.java
new file mode 100644
index 000000000..5a0ac3d7c
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/generate/AbstractTemplateSuiteGenerator.java
@@ -0,0 +1,132 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.generate;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.util.Map;
+
+import org.apache.tiles.autotag.core.AutotagRuntimeException;
+import org.apache.tiles.autotag.core.OutputLocator;
+import org.apache.tiles.autotag.model.TemplateSuite;
+import org.apache.tiles.autotag.tool.StringTool;
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
+import org.apache.velocity.exception.ParseErrorException;
+import org.apache.velocity.exception.ResourceNotFoundException;
+
+/**
+ * A base template suite generator.
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class AbstractTemplateSuiteGenerator implements TemplateSuiteGenerator {
+
+    /**
+     * The velocity engine.
+     */
+    private VelocityEngine velocityEngine;
+
+    /**
+     * Constructor.
+     *
+     * @param velocityEngine The Velocity engine.
+     */
+    public AbstractTemplateSuiteGenerator(VelocityEngine velocityEngine) {
+        this.velocityEngine = velocityEngine;
+    }
+
+    @Override
+    public void generate(OutputLocator outputLocator, String packageName, TemplateSuite suite, Map<String, String> parameters) {
+        String filePath =
+        		getDirectoryName(packageName, suite, parameters)
+                + File.separator
+                + getFilename(packageName, suite, parameters);
+		if (!outputLocator.isUptodate(filePath)) {
+	        VelocityContext context = new VelocityContext();
+	        context.put("packageName", packageName);
+	        context.put("suite", suite);
+	        context.put("stringTool", new StringTool());
+	        context.put("parameters", parameters);
+	        try {
+	            Template template = velocityEngine.getTemplate(getTemplatePath(
+	                    packageName, suite, parameters));
+	            Writer writer = new OutputStreamWriter(outputLocator.getOutputStream(filePath));
+	            try {
+	                template.merge(context, writer);
+	            } finally {
+	                writer.close();
+	            }
+	        } catch (ResourceNotFoundException e) {
+	            throw new AutotagRuntimeException("Cannot find template resource", e);
+	        } catch (ParseErrorException e) {
+	            throw new AutotagRuntimeException("The template resource is not parseable", e);
+	        } catch (IOException e) {
+	            throw new AutotagRuntimeException(
+	                    "I/O Exception when generating file", e);
+	        } catch (RuntimeException e) {
+	            throw e;
+	        } catch (Exception e) {
+	            throw new AutotagRuntimeException(
+	                    "Another generic exception while parsing the template resource",
+	                    e);
+	        }
+        }
+    }
+
+    /**
+     * Calculates and returns the template path.
+     *
+     * @param packageName The name of the package.
+     * @param suite The template suite.
+     * @param parameters The map of parameters.
+     * @return The template path.
+     */
+    protected abstract String getTemplatePath(
+            String packageName, TemplateSuite suite,
+            Map<String, String> parameters);
+
+    /**
+     * Calculates and returns the filename of the generated file.
+     *
+     * @param packageName The name of the package.
+     * @param suite The template suite.
+     * @param parameters The map of parameters.
+     * @return The template path.
+     */
+    protected abstract String getFilename(String packageName,
+            TemplateSuite suite, Map<String, String> parameters);
+
+    /**
+     * Calculates and returns the directory where the file will be written..
+     *
+     * @param packageName The name of the package.
+     * @param suite The template suite.
+     * @param parameters The map of parameters.
+     * @return The template path.
+     */
+    protected abstract String getDirectoryName(
+            String packageName, TemplateSuite suite,
+            Map<String, String> parameters);
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/generate/BasicTemplateGenerator.java b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/generate/BasicTemplateGenerator.java
new file mode 100644
index 000000000..ce64bd0d4
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/generate/BasicTemplateGenerator.java
@@ -0,0 +1,195 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.generate;
+
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tiles.autotag.core.OutputLocator;
+import org.apache.tiles.autotag.model.TemplateClass;
+import org.apache.tiles.autotag.model.TemplateSuite;
+
+/**
+ * The basic template generator. Use {@link TemplateGeneratorBuilder} to
+ * create instances of this class.
+ *
+ * @version $Rev$ $Date$
+ */
+class BasicTemplateGenerator implements TemplateGenerator {
+
+    /**
+     * The template suite generators.
+     */
+    private List<TSGeneratorDirectoryPair> templateSuiteGenerators;
+
+    /**
+     * The template class generators.
+     */
+    private List<TCGeneratorDirectoryPair> templateClassGenerators;
+
+    /**
+     * Indicates that this generator generates resources.
+     */
+    private boolean generatingResources = false;
+
+    /**
+     * Indicates that this generator generates classes.
+     */
+    private boolean generatingClasses = false;
+
+    /**
+     * Constructor.
+     *
+     * @param templateSuiteGenerators The template suite generators.
+     * @param templateClassGenerators The template class generators.
+     * @param generatingClasses Indicates that this generator generates classes.
+     * @param generatingResources Indicates that this generator generates resources.
+     */
+    BasicTemplateGenerator(
+            List<TSGeneratorDirectoryPair> templateSuiteGenerators,
+            List<TCGeneratorDirectoryPair> templateClassGenerators,
+            boolean generatingClasses, boolean generatingResources) {
+        this.templateSuiteGenerators = templateSuiteGenerators;
+        this.templateClassGenerators = templateClassGenerators;
+        this.generatingClasses = generatingClasses;
+        this.generatingResources = generatingResources;
+    }
+
+
+
+    @Override
+    public void generate(String packageName, TemplateSuite suite, Map<String, String> parameters,
+        String runtimeClass, String requestClass) {
+        for (TSGeneratorDirectoryPair pair : templateSuiteGenerators) {
+            pair.getGenerator().generate(pair.getOutputLocator(), packageName, suite, parameters);
+        }
+        for (TemplateClass templateClass : suite.getTemplateClasses()) {
+            for (TCGeneratorDirectoryPair pair : templateClassGenerators) {
+                pair.getGenerator().generate(pair.getOutputLocator(), packageName,
+                        suite, templateClass, parameters, runtimeClass, requestClass);
+            }
+        }
+    }
+
+    /**
+     * A pair of a template suite generator and a directory.
+     *
+     * @version $Rev$ $Date$
+     */
+    static class TSGeneratorDirectoryPair {
+        /**
+         * The directory where files are generated.
+         */
+        private OutputLocator outputLocator;
+
+        /**
+         * The generator.
+         */
+        private TemplateSuiteGenerator generator;
+
+        /**
+         * Constructor.
+         *
+         * @param directory The directory where files are generated.
+         * @param generator The generator.
+         */
+        public TSGeneratorDirectoryPair(OutputLocator outputLocator,
+                TemplateSuiteGenerator generator) {
+            this.outputLocator = outputLocator;
+            this.generator = generator;
+        }
+
+        /**
+         * Returns the directory where files are generated.
+         *
+         * @return The directory where files are generated.
+         */
+        public OutputLocator getOutputLocator() {
+            return outputLocator;
+        }
+
+        /**
+         * Returns the generator.
+         *
+         * @return The generator.
+         */
+        public TemplateSuiteGenerator getGenerator() {
+            return generator;
+        }
+    }
+
+    /**
+     * A pair of a template class generator and a directory.
+     *
+     * @version $Rev$ $Date$
+     */
+    static class TCGeneratorDirectoryPair {
+        /**
+         * The directory where files are generated.
+         */
+        private OutputLocator outputLocator;
+
+        /**
+         * The generator.
+         */
+        private TemplateClassGenerator generator;
+
+        /**
+         * Constructor.
+         *
+         * @param directory The directory where files are generated.
+         * @param generator The generator.
+         */
+        public TCGeneratorDirectoryPair(OutputLocator outputLocator,
+                TemplateClassGenerator generator) {
+            this.outputLocator = outputLocator;
+            this.generator = generator;
+        }
+
+        /**
+         * Returns the directory where files are generated.
+         *
+         * @return The directory where files are generated.
+         */
+        public OutputLocator getOutputLocator() {
+            return outputLocator;
+        }
+
+        /**
+         * Returns the generator.
+         *
+         * @return The generator.
+         */
+        public TemplateClassGenerator getGenerator() {
+            return generator;
+        }
+    }
+
+    @Override
+    public boolean isGeneratingResources() {
+        return generatingResources;
+    }
+
+    @Override
+    public boolean isGeneratingClasses() {
+        return generatingClasses;
+    }
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/generate/TemplateClassGenerator.java b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/generate/TemplateClassGenerator.java
new file mode 100644
index 000000000..bc60da467
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/generate/TemplateClassGenerator.java
@@ -0,0 +1,49 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.generate;
+
+import java.util.Map;
+
+import org.apache.tiles.autotag.core.OutputLocator;
+import org.apache.tiles.autotag.model.TemplateClass;
+import org.apache.tiles.autotag.model.TemplateSuite;
+
+/**
+ * Generates code from a parsed class.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface TemplateClassGenerator {
+
+    /**
+     * Generates the code.
+     *
+     * @param directory The base directory where the code will be put.
+     * @param packageName The package name.
+     * @param suite The template suite.
+     * @param clazz The template class.
+     * @param parameters Configuration parameters.
+     * @param runtimeClass The RequestBuilder implementation.
+     */
+    void generate(OutputLocator directory, String packageName, TemplateSuite suite,
+            TemplateClass clazz, Map<String, String> parameters,
+            String runtimeClass, String requestClass);
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/generate/TemplateGenerator.java b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/generate/TemplateGenerator.java
new file mode 100644
index 000000000..02450484f
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/generate/TemplateGenerator.java
@@ -0,0 +1,60 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.generate;
+
+
+import java.util.Map;
+
+import org.apache.tiles.autotag.model.TemplateSuite;
+
+/**
+ * Generates all the code for a template suite.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface TemplateGenerator {
+
+    /**
+     * Generates the code.
+     *
+     * @param packageName The package name.
+     * @param suite The template suite.
+     * @param parameters Configuration parameters.
+     * @param runtimeClass The RequestBuilder implementation.
+     * @param requestClass The request class to use.
+     */
+    void generate(String packageName, TemplateSuite suite, Map<String, String> parameters,
+        String runtimeClass, String requestClass);
+
+    /**
+     * Indicates that this generator generates resources.
+     *
+     * @return <code>true</code> if the generator generates resources.
+     */
+    boolean isGeneratingResources();
+
+    /**
+     * Indicates that this generator generates classes.
+     *
+     * @return <code>true</code> if the generator generates classes.
+     */
+    boolean isGeneratingClasses();
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/generate/TemplateGeneratorBuilder.java b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/generate/TemplateGeneratorBuilder.java
new file mode 100644
index 000000000..263bfccfb
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/generate/TemplateGeneratorBuilder.java
@@ -0,0 +1,184 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.generate;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tiles.autotag.core.OutputLocator;
+import org.apache.tiles.autotag.generate.BasicTemplateGenerator.TCGeneratorDirectoryPair;
+import org.apache.tiles.autotag.generate.BasicTemplateGenerator.TSGeneratorDirectoryPair;
+
+/**
+ * Builds a {@link TemplateGenerator}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TemplateGeneratorBuilder {
+
+    /**
+     * The template suite generators.
+     */
+    private List<TSGeneratorDirectoryPair> templateSuiteGenerators;
+
+    /**
+     * The template class generators.
+     */
+    private List<TCGeneratorDirectoryPair> templateClassGenerators;
+
+    /**
+     * Indicates that this generator generates resources.
+     */
+    private boolean generatingResources = false;
+
+    /**
+     * Indicates that this generator generates classes.
+     */
+    private boolean generatingClasses = false;
+
+    /**
+     * The classes output directory.
+     */
+    private OutputLocator classesOutputLocator;
+
+    /**
+     * The resources output directory.
+     */
+    private OutputLocator resourcesOutputLocator;
+
+    /**
+     * Constructor.
+     */
+    private TemplateGeneratorBuilder() {
+        templateSuiteGenerators = new ArrayList<BasicTemplateGenerator.TSGeneratorDirectoryPair>();
+        templateClassGenerators = new ArrayList<BasicTemplateGenerator.TCGeneratorDirectoryPair>();
+    }
+
+    /**
+     * Creates a new instance of the builder.
+     *
+     * @return A new instance of the builder.
+     */
+    public static TemplateGeneratorBuilder createNewInstance() {
+        return new TemplateGeneratorBuilder();
+    }
+
+    /**
+     * Sets the classes output directory.
+     *
+     * @param classesOutputDirectory The classes output directory.
+     * @return This instance.
+     */
+    public TemplateGeneratorBuilder setClassesOutputLocator(OutputLocator classesOutputLocator) {
+        this.classesOutputLocator = classesOutputLocator;
+        return this;
+    }
+
+    /**
+     * Sets the resources output directory.
+     *
+     * @param resourcesOutputDirectory The resources output directory.
+     * @return This instance.
+     */
+    public TemplateGeneratorBuilder setResourcesOutputLocator(OutputLocator resourcesOutputLocator) {
+        this.resourcesOutputLocator = resourcesOutputLocator;
+        return this;
+    }
+
+    /**
+     * Adds a new template suite generator to generate classes.
+     *
+     * @param generator The generator to add.
+     * @return This instance.
+     */
+    public TemplateGeneratorBuilder addClassesTemplateSuiteGenerator(TemplateSuiteGenerator generator) {
+        if (classesOutputLocator == null) {
+            throw new NullPointerException(
+                    "Classes output locator not specified, call 'setClassesOutputLocator' first");
+        }
+        templateSuiteGenerators.add(new TSGeneratorDirectoryPair(
+                classesOutputLocator, generator));
+        generatingClasses = true;
+        return this;
+    }
+
+    /**
+     * Adds a new template class generator to generate classes.
+     *
+     * @param generator The generator to add.
+     * @return This instance.
+     */
+    public TemplateGeneratorBuilder addClassesTemplateClassGenerator(TemplateClassGenerator generator) {
+        if (classesOutputLocator == null) {
+            throw new NullPointerException(
+                    "Classes output locator not specified, call 'setClassesOutputLocator' first");
+        }
+        templateClassGenerators.add(new TCGeneratorDirectoryPair(
+                classesOutputLocator, generator));
+        generatingClasses = true;
+        return this;
+    }
+
+    /**
+     * Adds a new template suite generator to generate resources.
+     *
+     * @param generator The generator to add.
+     * @return This instance.
+     */
+    public TemplateGeneratorBuilder addResourcesTemplateSuiteGenerator(TemplateSuiteGenerator generator) {
+        if (resourcesOutputLocator == null) {
+            throw new NullPointerException(
+                    "Resources output locator not specified, call 'setClassesOutputLocator' first");
+        }
+        templateSuiteGenerators.add(new TSGeneratorDirectoryPair(
+                resourcesOutputLocator, generator));
+        generatingResources = true;
+        return this;
+    }
+
+    /**
+     * Adds a new template class generator to generate resources.
+     *
+     * @param generator The generator to add.
+     * @return This instance.
+     */
+    public TemplateGeneratorBuilder addResourcesTemplateClassGenerator(TemplateClassGenerator generator) {
+        if (resourcesOutputLocator == null) {
+            throw new NullPointerException(
+                    "Resources output locator not specified, call 'setClassesOutputLocator' first");
+        }
+        templateClassGenerators.add(new TCGeneratorDirectoryPair(
+        		resourcesOutputLocator, generator));
+        generatingResources = true;
+        return this;
+    }
+
+    /**
+     * Builds and returns a new template generator.
+     *
+     * @return The new template generator.
+     */
+    public TemplateGenerator build() {
+        return new BasicTemplateGenerator(templateSuiteGenerators,
+                templateClassGenerators, generatingClasses, generatingResources);
+    }
+
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/generate/TemplateGeneratorFactory.java b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/generate/TemplateGeneratorFactory.java
new file mode 100644
index 000000000..76b40d7e3
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/generate/TemplateGeneratorFactory.java
@@ -0,0 +1,36 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.generate;
+
+/**
+ * Creates a new template generator.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface TemplateGeneratorFactory {
+
+    /**
+     * Creates a template generator.
+     *
+     * @return The newly created template generator.
+     */
+    TemplateGenerator createTemplateGenerator();
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/generate/TemplateSuiteGenerator.java b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/generate/TemplateSuiteGenerator.java
new file mode 100644
index 000000000..da7bb7aa9
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/generate/TemplateSuiteGenerator.java
@@ -0,0 +1,44 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.generate;
+
+import java.util.Map;
+
+import org.apache.tiles.autotag.core.OutputLocator;
+import org.apache.tiles.autotag.model.TemplateSuite;
+
+/**
+ * Generates code from a template suite.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface TemplateSuiteGenerator {
+
+    /**
+     * Generates the code.
+     *
+     * @param outputLocator The base directory where the code will be put.
+     * @param packageName The package name.
+     * @param suite The template suite.
+     * @param parameters Configuration parameters.
+     */
+    void generate(OutputLocator outputLocator, String packageName, TemplateSuite suite, Map<String, String> parameters);
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/generate/package-info.java b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/generate/package-info.java
new file mode 100644
index 000000000..6256497fb
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/generate/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * The Autotag generation classes.
+ */
+package org.apache.tiles.autotag.generate;
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/model/TemplateClass.java b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/model/TemplateClass.java
new file mode 100644
index 000000000..f869c9526
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/model/TemplateClass.java
@@ -0,0 +1,195 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.model;
+
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * It represents a parsed template class.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TemplateClass {
+
+    /**
+     * The class name.
+     */
+    private String name;
+
+    /**
+     * The name of the tag.
+     */
+    private String tagName;
+
+    /**
+     * The prefix of the tag class.
+     */
+    private String tagClassPrefix;
+
+    /**
+     * Documentation about this tag.
+     */
+    private String documentation;
+
+    /**
+     * The method that executes the template class.
+     */
+    private TemplateMethod executeMethod;
+
+    /**
+     * Constructor.
+     *
+     * @param name The name of the template class.
+     */
+    public TemplateClass(String name) {
+        this(name, null, null, null);
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param name The name of the template class.
+     * @param tagName The name of the tag.
+     * @param tagClassPrefix The tag class prefix.
+     * @param executeMethod The method that executes the template class.
+     */
+    public TemplateClass(String name, String tagName, String tagClassPrefix,
+            TemplateMethod executeMethod) {
+        this.name = name;
+        this.tagName = tagName;
+        this.tagClassPrefix = tagClassPrefix;
+        this.executeMethod = executeMethod;
+    }
+
+    /**
+     * The name of the parsed class.
+     *
+     * @return The name of the class.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Returns the name of the class, without the package part.
+     *
+     * @return The simple class name.
+     */
+    public String getSimpleName() {
+        int pos = name.lastIndexOf('.');
+        if (pos >= 0) {
+            return name.substring(pos + 1);
+        }
+        return name;
+    }
+
+    /**
+     * Returns the tag name.
+     *
+     * @return The tag name.
+     */
+    public String getTagName() {
+        return tagName;
+    }
+
+    /**
+     * Returns the tag class prefix.
+     *
+     * @return The tag class prefix.
+     */
+    public String getTagClassPrefix() {
+        return tagClassPrefix;
+    }
+
+    /**
+     * Returns the documentation for this class.
+     *
+     * @return The documentation.
+     */
+    public String getDocumentation() {
+        return documentation;
+    }
+
+    /**
+     * Sets the documentation for this class.
+     *
+     * @param documentation The documentation.
+     */
+    public void setDocumentation(String documentation) {
+        this.documentation = documentation;
+    }
+
+    /**
+     * Returns the method that execute this class.
+     *
+     * @return The execute method.
+     */
+    public TemplateMethod getExecuteMethod() {
+        return executeMethod;
+    }
+
+    /**
+     * Returns the collection of regular parameters (no request, no body)
+     * of the execute method.
+     *
+     * @return The regular parameters.
+     */
+    public Collection<TemplateParameter> getParameters() {
+        Map<String, TemplateParameter> params = new LinkedHashMap<String, TemplateParameter>();
+        fillRegularParameters(params, executeMethod);
+        return params.values();
+    }
+
+    /**
+     * Indicates that this class needs a tag body.
+     *
+     * @return <code>true</code> if tag body is needed.
+     */
+    public boolean hasBody() {
+        return executeMethod.hasBody();
+    }
+
+    @Override
+    public String toString() {
+        return "TemplateClass [name=" + name + ", tagName=" + tagName
+                + ", tagClassPrefix=" + tagClassPrefix + ", documentation="
+                + documentation + ", executeMethod=" + executeMethod + "]";
+    }
+
+    /**
+     * Creates regular parameters map.
+     *
+     * @param params The map to fill.
+     * @param method The method to analyze.
+     */
+    private void fillRegularParameters(Map<String, TemplateParameter> params,
+            TemplateMethod method) {
+        if (method != null) {
+            for (TemplateParameter param : method.getParameters()) {
+                if (!param.isRequest() && !param.isBody()) {
+                    params.put(param.getName(), param);
+                }
+            }
+        }
+    }
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/model/TemplateMethod.java b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/model/TemplateMethod.java
new file mode 100644
index 000000000..d5703c54e
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/model/TemplateMethod.java
@@ -0,0 +1,131 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.model;
+
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * It represents a parsed method in a parsed template class.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TemplateMethod {
+
+    /**
+     * The name of the method.
+     */
+    private String name;
+
+    /**
+     * Documentation about the method.
+     */
+    private String documentation;
+
+    /**
+     * The map of parameters.
+     */
+    private Map<String, TemplateParameter> parameters;
+
+    /**
+     * Constructor.
+     *
+     * @param name The name of the method.
+     * @param parameters The map of parameters.
+     */
+    public TemplateMethod(String name,
+            Iterable<? extends TemplateParameter> parameters) {
+        this.name = name;
+        this.parameters = new LinkedHashMap<String, TemplateParameter>();
+        for (TemplateParameter parameter : parameters) {
+            this.parameters.put(parameter.getName(), parameter);
+        }
+    }
+
+    /**
+     * Returns the name of the method.
+     *
+     * @return The name of the method.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Returns the documentation for this method.
+     *
+     * @return The documentation.
+     */
+    public String getDocumentation() {
+        return documentation;
+    }
+
+    /**
+     * Sets the documentation for this method.
+     *
+     * @param documentation The documentation.
+     */
+    public void setDocumentation(String documentation) {
+        this.documentation = documentation;
+    }
+
+    /**
+     * Returns the parameters of this method.
+     *
+     * @return The parameters.
+     */
+    public Collection<TemplateParameter> getParameters() {
+        return parameters.values();
+    }
+
+    /**
+     * Returns a parameter given its name.
+     *
+     * @param name The name of the parameter.
+     * @return The parameter.
+     */
+    public TemplateParameter getParameterByName(String name) {
+        return parameters.get(name);
+    }
+
+    /**
+     * Indicates that this method needs a tag body.
+     *
+     * @return <code>true</code> if tag body is needed.
+     */
+    public boolean hasBody() {
+        if (parameters.size() >= 2) {
+            for (TemplateParameter param : parameters.values()) {
+                if (param.isBody()) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return "TemplateMethod [name=" + name + ", documentation="
+                + documentation + ", parameters=" + parameters + "]";
+    }
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/model/TemplateParameter.java b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/model/TemplateParameter.java
new file mode 100644
index 000000000..360e019ee
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/model/TemplateParameter.java
@@ -0,0 +1,186 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.model;
+
+import org.apache.tiles.autotag.core.runtime.ModelBody;
+
+/**
+ * It represents a parameter in a method in a parsed template class.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TemplateParameter {
+
+    /**
+     * The name of the parameter.
+     */
+    private String name;
+
+    /**
+     * The exported name, i.e. the name of the parameter in created code. Usually
+     * helpful if this exported name is a reserved word.
+     */
+    private String exportedName;
+
+    /**
+     * The parameter documentation.
+     */
+    private String documentation;
+
+    /**
+     * The type of the parameter.
+     */
+    private String type;
+
+    /**
+     * The default value, as it will be written in Java code.
+     */
+    private String defaultValue;
+
+    /**
+     * Indicates that this parameter is required.
+     */
+    private boolean required;
+
+    /**
+     * Indicates that this parameter is the request.
+     */
+    private boolean request;
+
+    /**
+     * Constructor.
+     *
+     * @param name The name of the parameter.
+     * @param exportedName The exported name, i.e. the name of the parameter in created code. Usually
+     * helpful if this exported name is a reserved word.
+     * @param type The type of the parameter.
+     * @param defaultValue The default value, as it will be written in Java code.
+     * @param required Indicates that this parameter is required.
+     */
+    public TemplateParameter(String name, String exportedName, String type, String defaultValue, boolean required, boolean request) {
+        this.name = name;
+        this.exportedName = exportedName;
+        this.type = type;
+        this.defaultValue = defaultValue;
+        this.required = required;
+        this.request = request;
+    }
+
+    /**
+     * Returns the documentation for this parameter.
+     *
+     * @return The documentation.
+     */
+    public String getDocumentation() {
+        return documentation;
+    }
+
+    /**
+     * Sets the documentation for this parameter.
+     *
+     * @param documentation The documentation.
+     */
+    public void setDocumentation(String documentation) {
+        this.documentation = documentation;
+    }
+
+    /**
+     * Returns the name of the parameter.
+     *
+     * @return The name of the parameter.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Returns the exported name, i.e. the name of the parameter in created code. Usually
+     * helpful if this exported name is a reserved word.
+     *
+     * @return The exported name.
+     */
+    public String getExportedName() {
+        return exportedName;
+    }
+
+    /**
+     * Returns the type of the parameter.
+     *
+     * @return The type.
+     */
+    public String getType() {
+        return type;
+    }
+
+    /**
+     * Returns the default value, as it will be written in Java code.
+     *
+     * @return The default value.
+     */
+    public String getDefaultValue() {
+        return defaultValue;
+    }
+
+    /**
+     * Indicates that this parameter is required.
+     *
+     * @return <code>true</code> if the parameter is required.
+     */
+    public boolean isRequired() {
+        return required;
+    }
+
+    /**
+     * Indicates that this parameter implements {@link ModelBody}.
+     *
+     * @return <code>true</code> if the parameter is a body.
+     */
+    public boolean isBody() {
+        return ModelBody.class.getName().equals(type);
+    }
+
+    /**
+     * Indicates that this parameter implements {@link Request}.
+     *
+     * @return <code>true</code> if the parameter is a request.
+     */
+    public boolean isRequest() {
+        return request;
+    }
+
+    /**
+     * Returns the suffix for getter and setter of the property generated by
+     * this parameter.
+     *
+     * @return The getter and setter suffix.
+     */
+    public String getGetterSetterSuffix() {
+        return exportedName.substring(0, 1).toUpperCase() + exportedName.substring(1);
+    }
+
+    @Override
+    public String toString() {
+        return "TemplateParameter [name=" + name + ", exportedName="
+                + exportedName + ", documentation=" + documentation + ", type="
+                + type + ", defaultValue=" + defaultValue + ", required="
+                + required + ", request=" + request + "]";
+    }
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/model/TemplateSuite.java b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/model/TemplateSuite.java
new file mode 100644
index 000000000..25361c866
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/model/TemplateSuite.java
@@ -0,0 +1,129 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.model;
+
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * It represents a suite of template classes.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TemplateSuite {
+
+    /**
+     * The name of the suite.
+     */
+    private String name;
+
+    /**
+     * The documentation of this suite.
+     */
+    private String documentation;
+
+    /**
+     * The map of template classes.
+     */
+    private Map<String, TemplateClass> templateClasses;
+
+    /**
+     * Constructor.
+     *
+     * @param name The name of the suite.
+     * @param documentation The documentation.
+     */
+    public TemplateSuite(String name, String documentation) {
+        this(name, documentation, null);
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param name The name of the suite.
+     * @param documentation The documentation.
+     * @param classes The template classes.
+     */
+    public TemplateSuite(String name, String documentation,
+            Iterable<? extends TemplateClass> classes) {
+        this.name = name;
+        this.documentation = documentation;
+        templateClasses = new LinkedHashMap<String, TemplateClass>();
+        if (classes != null) {
+            for (TemplateClass templateClass : classes) {
+                templateClasses.put(templateClass.getName(), templateClass);
+            }
+        }
+    }
+
+    /**
+     * Returns the template suite name.
+     *
+     * @return The name.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Returns the documentation.
+     *
+     * @return The documentation.
+     */
+    public String getDocumentation() {
+        return documentation;
+    }
+
+    /**
+     * Adds a new template class.
+     *
+     * @param clazz The template class.
+     */
+    public void addTemplateClass(TemplateClass clazz) {
+        templateClasses.put(clazz.getName(), clazz);
+    }
+
+    /**
+     * Returns the template classes.
+     *
+     * @return The template classes.
+     */
+    public Collection<TemplateClass> getTemplateClasses() {
+        return templateClasses.values();
+    }
+
+    /**
+     * Returns a template class given its name.
+     *
+     * @param name The name of the class.
+     * @return The template class instance.
+     */
+    public TemplateClass getTemplateClassByName(String name) {
+        return templateClasses.get(name);
+    }
+
+    @Override
+    public String toString() {
+        return "TemplateSuite [name=" + name + ", documentation="
+                + documentation + ", templateClasses=" + templateClasses + "]";
+    }
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/model/TemplateSuiteFactory.java b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/model/TemplateSuiteFactory.java
new file mode 100644
index 000000000..4c45ebcc3
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/model/TemplateSuiteFactory.java
@@ -0,0 +1,37 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.model;
+
+
+/**
+ * Creates a new template suite.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface TemplateSuiteFactory {
+
+    /**
+     * Creates a template suite.
+     *
+     * @return The created template suite.
+     */
+    TemplateSuite createTemplateSuite();
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/model/package-info.java b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/model/package-info.java
new file mode 100644
index 000000000..a1130d2aa
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/model/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * Domain model classes representing a parsed template suite.
+ */
+package org.apache.tiles.autotag.model;
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/tool/StringTool.java b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/tool/StringTool.java
new file mode 100644
index 000000000..7341feb33
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/tool/StringTool.java
@@ -0,0 +1,143 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.tool;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tiles.autotag.core.AutotagRuntimeException;
+
+/**
+ * A Velocity tools to manipulate strings.
+ *
+ * @version $Rev$ $Date$
+ */
+public class StringTool {
+
+    /**
+     * Maps a primitive type to its default value as a string.
+     */
+    private Map<String, String> type2default;
+
+    /**
+     * Maps a primitive type to its boxed version.
+     */
+    private Map<String, String> primitive2wrapped;
+
+    /**
+     * Constructor.
+     */
+    public StringTool() {
+        type2default = new HashMap<String, String>();
+        type2default.put("byte", "0");
+        type2default.put("short", "0");
+        type2default.put("int", "0");
+        type2default.put("long", "0L");
+        type2default.put("float", "0.0f");
+        type2default.put("double", "0.0d");
+        type2default.put("char", "'\\u0000'");
+        type2default.put("boolean", "false");
+
+        primitive2wrapped = new HashMap<String, String>();
+        primitive2wrapped.put("byte", Byte.class.getName());
+        primitive2wrapped.put("short", Short.class.getName());
+        primitive2wrapped.put("int", Integer.class.getName());
+        primitive2wrapped.put("long", Long.class.getName());
+        primitive2wrapped.put("float", Float.class.getName());
+        primitive2wrapped.put("double", Double.class.getName());
+        primitive2wrapped.put("char", Character.class.getName());
+        primitive2wrapped.put("boolean", Boolean.class.getName());
+    }
+
+    /**
+     * Creates a list of strings, separating a string when a newline is encountered.
+     *
+     * @param toSplit The string to split.
+     * @return The list of splitted strings.
+     */
+    public List<String> splitOnNewlines(String toSplit) {
+        List<String> retValue = new ArrayList<String>();
+        if (toSplit == null) {
+            return retValue;
+        }
+        Reader reader = new StringReader(toSplit);
+        BufferedReader bufReader = new BufferedReader(reader);
+        try {
+            String line;
+            while ((line = bufReader.readLine()) != null) {
+                retValue.add(line);
+            }
+        } catch (IOException e) {
+            throw new AutotagRuntimeException(
+                    "Cannot read the string completely", e);
+        }
+        return retValue;
+    }
+
+    /**
+     * Creates a string in which the first character is capitalized.
+     *
+     * @param string The string to use.
+     * @return The same string with the first character capitalized.
+     */
+    public String capitalizeFirstLetter(String string) {
+        return string.substring(0, 1).toUpperCase() + string.substring(1);
+    }
+
+    /**
+     * Returns the default value for a type.
+     *
+     * @param type The type.
+     * @param overriddenDefaultValue The default value, as specified by developers.
+     * @return The default value to use.
+     */
+    public String getDefaultValue(String type, String overriddenDefaultValue) {
+        if (overriddenDefaultValue != null) {
+            return overriddenDefaultValue;
+        }
+
+        String retValue = type2default.get(type);
+        if (retValue == null) {
+            retValue = "null";
+        }
+        return retValue;
+    }
+
+    /**
+     * Returns the class to be used to cast an Object.
+     *
+     * @param type The type to use, even a primitive type.
+     * @return The class to be used in casts.
+     */
+    public String getClassToCast(String type) {
+        String retValue = primitive2wrapped.get(type);
+        if (retValue == null) {
+            retValue = type;
+        }
+        return retValue;
+    }
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/tool/package-info.java b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/tool/package-info.java
new file mode 100644
index 000000000..558c330e9
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/java/org/apache/tiles/autotag/tool/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * Velocity tools to be used in Velocity templates.
+ */
+package org.apache.tiles.autotag.tool;
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/resources/org/apache/tiles/autotag/velocity.properties b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/resources/org/apache/tiles/autotag/velocity.properties
new file mode 100644
index 000000000..0a9f2a57d
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core/src/main/resources/org/apache/tiles/autotag/velocity.properties
@@ -0,0 +1,115 @@
+# 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.
+
+# ----------------------------------------------------------------------------
+# These are the default properties for the
+# Velocity Runtime. These values are used when
+# Runtime.init() is called, and when Runtime.init(properties)
+# fails to find the specificed properties file.
+# ----------------------------------------------------------------------------
+
+
+# ----------------------------------------------------------------------------
+# R U N T I M E  L O G
+# ----------------------------------------------------------------------------
+# Velocity uses the Servlet APIs logging facilites.
+
+# ----------------------------------------------------------------------------
+# This controls if Runtime.error(), info() and warn() messages include the
+# whole stack trace. The last property controls whether invalid references
+# are logged.
+# ----------------------------------------------------------------------------
+
+runtime.log.invalid.reference = true
+
+
+# ----------------------------------------------------------------------------
+# T E M P L A T E  E N C O D I N G
+# ----------------------------------------------------------------------------
+
+input.encoding=ISO-8859-1
+output.encoding=ISO-8859-1
+
+
+# ----------------------------------------------------------------------------
+# F O R E A C H  P R O P E R T I E S
+# ----------------------------------------------------------------------------
+# These properties control how the counter is accessed in the #foreach
+# directive. By default the reference $velocityCount will be available
+# in the body of the #foreach directive. The default starting value
+# for this reference is 1.
+# ----------------------------------------------------------------------------
+
+directive.foreach.counter.name = velocityCount
+directive.foreach.counter.initial.value = 1
+
+
+# ----------------------------------------------------------------------------
+# I N C L U D E  P R O P E R T I E S
+# ----------------------------------------------------------------------------
+# These are the properties that governed the way #include'd content
+# is governed.
+# ----------------------------------------------------------------------------
+
+directive.include.output.errormsg.start = <!-- include error :
+directive.include.output.errormsg.end   =  see error log -->
+
+
+# ----------------------------------------------------------------------------
+# P A R S E  P R O P E R T I E S
+# ----------------------------------------------------------------------------
+
+directive.parse.max.depth = 10
+
+
+# ----------------------------------------------------------------------------
+# VELOCIMACRO PROPERTIES
+# ----------------------------------------------------------------------------
+# global : name of default global library.  It is expected to be in the regular
+# template path.  You may remove it (either the file or this property) if
+# you wish with no harm.
+# ----------------------------------------------------------------------------
+# dev-changes by Marino
+resource.loader=class, string
+
+class.resource.loader.class=org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
+
+velocimacro.library.autoreload = false
+
+velocimacro.permissions.allow.inline = true
+velocimacro.permissions.allow.inline.to.replace.global = false
+velocimacro.permissions.allow.inline.local.scope = false
+
+velocimacro.context.localscope = false
+
+# ----------------------------------------------------------------------------
+# INTERPOLATION
+# ----------------------------------------------------------------------------
+# turn off and on interpolation of references and directives in string
+# literals.  ON by default :)
+# ----------------------------------------------------------------------------
+runtime.interpolate.string.literals = true
+
+
+# ----------------------------------------------------------------------------
+# RESOURCE MANAGEMENT
+# ----------------------------------------------------------------------------
+# Allows alternative ResourceManager and ResourceCache implementations
+# to be plugged in.
+# ----------------------------------------------------------------------------
+resource.manager.class = org.apache.velocity.runtime.resource.ResourceManagerImpl
+resource.manager.cache.class = org.apache.velocity.runtime.resource.ResourceCacheImpl
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core/src/site/site.xml b/Java-base/tiles-autotag/src/tiles-autotag-core/src/site/site.xml
new file mode 100644
index 000000000..0a7d00df4
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core/src/site/site.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+/*
+ * $Id: site.xml 1081442 2011-03-14 16:21:08Z apetrelli $
+ *
+ * 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.
+ */
+-->
+<project name="Apache - Tiles Autotags">
+    <bannerLeft>
+        <name>Apache Software Foundation</name>
+        <src>http://www.apache.org/images/asf-logo.gif</src>
+        <href>http://www.apache.org</href>
+    </bannerLeft>
+    <bannerRight>
+        <name>Apache Tiles&#8482;</name>
+        <src>http://tiles.apache.org/images/logo.png</src>
+        <href>http://tiles.apache.org</href>
+    </bannerRight>
+    <body>
+
+        <links>
+            <item name="Apache" href="http://www.apache.org" />
+            <item name="Tiles" href="http://tiles.apache.org" />
+        </links>
+
+
+        <menu name="Apache Tiles&#8482;">
+            <item
+                   name="Tiles Home"
+                   href="../../index.html"/>
+            <item
+                   name="Tiles Autotag"
+                   href="../index.html"/>
+        </menu>
+
+        <menu ref="modules" />
+        <menu ref="reports" />
+
+    </body>
+</project>
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/core/AutotagRuntimeExceptionTest.java b/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/core/AutotagRuntimeExceptionTest.java
new file mode 100644
index 000000000..bf3338a12
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/core/AutotagRuntimeExceptionTest.java
@@ -0,0 +1,77 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.autotag.core;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+/**
+ * Tests {@link AutotagRuntimeException}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class AutotagRuntimeExceptionTest {
+
+    /**
+     * Test method for {@link AutotagRuntimeException#AutotagRuntimeException()}.
+     */
+    @Test
+    public void testAutotagRuntimeException() {
+        AutotagRuntimeException exception = new AutotagRuntimeException();
+        assertNull(exception.getMessage());
+        assertNull(exception.getCause());
+    }
+
+    /**
+     * Test method for {@link AutotagRuntimeException#AutotagRuntimeException(java.lang.String)}.
+     */
+    @Test
+    public void testAutotagRuntimeExceptionString() {
+        AutotagRuntimeException exception = new AutotagRuntimeException("my message");
+        assertEquals("my message", exception.getMessage());
+        assertNull(exception.getCause());
+    }
+
+    /**
+     * Test method for {@link AutotagRuntimeException#AutotagRuntimeException(java.lang.Throwable)}.
+     */
+    @Test
+    public void testAutotagRuntimeExceptionThrowable() {
+        Throwable cause = new Throwable();
+        AutotagRuntimeException exception = new AutotagRuntimeException(cause);
+        assertEquals(cause.toString(), exception.getMessage());
+        assertEquals(cause, exception.getCause());
+    }
+
+    /**
+     * Test method for {@link AutotagRuntimeException#AutotagRuntimeException(java.lang.String, java.lang.Throwable)}.
+     */
+    @Test
+    public void testAutotagRuntimeExceptionStringThrowable() {
+        Throwable cause = new Throwable();
+        AutotagRuntimeException exception = new AutotagRuntimeException("my message", cause);
+        assertEquals("my message", exception.getMessage());
+        assertEquals(cause, exception.getCause());
+    }
+
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/core/ClassParseExceptionTest.java b/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/core/ClassParseExceptionTest.java
new file mode 100644
index 000000000..c3b2ae6f4
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/core/ClassParseExceptionTest.java
@@ -0,0 +1,77 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.autotag.core;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+/**
+ * Tests {@link ClassParseException}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ClassParseExceptionTest {
+
+    /**
+     * Test method for {@link ClassParseException#ClassParseException()}.
+     */
+    @Test
+    public void testClassParseException() {
+        ClassParseException exception = new ClassParseException();
+        assertNull(exception.getMessage());
+        assertNull(exception.getCause());
+    }
+
+    /**
+     * Test method for {@link ClassParseException#ClassParseException(java.lang.String)}.
+     */
+    @Test
+    public void testClassParseExceptionString() {
+        ClassParseException exception = new ClassParseException("my message");
+        assertEquals("my message", exception.getMessage());
+        assertNull(exception.getCause());
+    }
+
+    /**
+     * Test method for {@link ClassParseException#ClassParseException(java.lang.Throwable)}.
+     */
+    @Test
+    public void testClassParseExceptionThrowable() {
+        Throwable cause = new Throwable();
+        ClassParseException exception = new ClassParseException(cause);
+        assertEquals(cause.toString(), exception.getMessage());
+        assertEquals(cause, exception.getCause());
+    }
+
+    /**
+     * Test method for {@link ClassParseException#ClassParseException(java.lang.String, java.lang.Throwable)}.
+     */
+    @Test
+    public void testClassParseExceptionStringThrowable() {
+        Throwable cause = new Throwable();
+        ClassParseException exception = new ClassParseException("my message", cause);
+        assertEquals("my message", exception.getMessage());
+        assertEquals(cause, exception.getCause());
+    }
+
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/core/QDoxTemplateSuiteFactoryTest.java b/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/core/QDoxTemplateSuiteFactoryTest.java
new file mode 100644
index 000000000..c648716ee
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/core/QDoxTemplateSuiteFactoryTest.java
@@ -0,0 +1,150 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.core;
+
+import static org.junit.Assert.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tiles.autotag.core.internal.AnnotatedExampleModel;
+import org.apache.tiles.autotag.core.internal.ExampleExecutableModel;
+import org.apache.tiles.autotag.core.internal.ExampleModel;
+import org.apache.tiles.autotag.core.internal.ExampleRequest;
+import org.apache.tiles.autotag.core.internal.NotFeasibleExampleModel;
+import org.apache.tiles.autotag.core.runtime.ModelBody;
+import org.apache.tiles.autotag.model.TemplateClass;
+import org.apache.tiles.autotag.model.TemplateMethod;
+import org.apache.tiles.autotag.model.TemplateParameter;
+import org.apache.tiles.autotag.model.TemplateSuite;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests {@link QDoxTemplateSuiteFactory}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class QDoxTemplateSuiteFactoryTest {
+
+    private static final String REQUEST_CLASS = ExampleRequest.class.getName();
+    /**
+     * The factory to test.
+     */
+    private QDoxTemplateSuiteFactory factory;
+
+    /**
+     * @throws java.lang.Exception
+     */
+    @Before
+    public void setUp() {
+        factory = new QDoxTemplateSuiteFactory(
+                getClass().getResource("/org/apache/tiles/autotag/core/internal/ExampleModel.java"),
+                getClass().getResource("/org/apache/tiles/autotag/core/internal/AnnotatedExampleModel.java"),
+                getClass().getResource("/org/apache/tiles/autotag/core/internal/ExampleExcluded.java"),
+                getClass().getResource("/org/apache/tiles/autotag/core/internal/ExampleExecutableModel.java"),
+                getClass().getResource("/org/apache/tiles/autotag/core/internal/NotFeasibleExampleModel.java"));
+        factory.setSuiteName("The suite name");
+        factory.setSuiteDocumentation("This are the docs");
+        factory.setRequestClass(REQUEST_CLASS);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.autotag.core.DefaultTemplateSuiteFactory#createTemplateSuite()}.
+     */
+    @Test
+    public void testCreateTemplateSuite() {
+        TemplateSuite suite = factory.createTemplateSuite();
+        assertEquals("The suite name", suite.getName());
+        assertEquals("This are the docs", suite.getDocumentation());
+        assertEquals(3, suite.getTemplateClasses().size());
+
+        TemplateClass templateClass = suite.getTemplateClassByName(ExampleModel.class.getName());
+        assertNotNull(templateClass);
+        assertEquals(ExampleModel.class.getName(), templateClass.getName());
+        assertEquals("Example start/stop template.", templateClass.getDocumentation());
+        TemplateMethod templateMethod = templateClass.getExecuteMethod();
+        assertNotNull(templateMethod);
+        assertTrue(templateMethod.hasBody());
+        assertTrue(templateClass.hasBody());
+        assertEquals("execute", templateMethod.getName());
+        assertEquals("It starts.", templateMethod.getDocumentation());
+        List<TemplateParameter> parameters = new ArrayList<TemplateParameter>(templateMethod.getParameters());
+        assertEquals(4, parameters.size());
+        TemplateParameter parameter = parameters.get(0);
+        assertEquals("one", parameter.getName());
+        assertEquals("java.lang.String", parameter.getType());
+        assertEquals("Parameter one.", parameter.getDocumentation());
+        parameter = parameters.get(1);
+        assertEquals("two", parameter.getName());
+        assertEquals("int", parameter.getType());
+        assertEquals("Parameter two.", parameter.getDocumentation());
+        parameter = parameters.get(2);
+        assertEquals("request", parameter.getName());
+        assertEquals(REQUEST_CLASS, parameter.getType());
+        assertEquals("The request.", parameter.getDocumentation());
+        parameter = parameters.get(3);
+        assertEquals("modelBody", parameter.getName());
+        assertEquals(ModelBody.class.getName(), parameter.getType());
+        assertEquals("The model body.", parameter.getDocumentation());
+
+        templateClass = suite.getTemplateClassByName(AnnotatedExampleModel.class.getName());
+        assertNotNull(templateClass);
+        assertEquals(AnnotatedExampleModel.class.getName(), templateClass.getName());
+        templateMethod = templateClass.getExecuteMethod();
+        assertNotNull(templateMethod);
+        assertEquals("execute", templateMethod.getName());
+        parameters = new ArrayList<TemplateParameter>(templateMethod.getParameters());
+        assertEquals(4, parameters.size());
+        parameter = parameters.get(0);
+        assertEquals("one", parameter.getName());
+        assertEquals("alternateOne", parameter.getExportedName());
+        assertEquals("java.lang.String", parameter.getType());
+        assertEquals("Parameter one.", parameter.getDocumentation());
+        assertEquals("hello", parameter.getDefaultValue());
+        assertTrue(parameter.isRequired());
+
+        templateClass = suite.getTemplateClassByName(ExampleExecutableModel.class.getName());
+        assertNotNull(templateClass);
+        assertEquals(ExampleExecutableModel.class.getName(), templateClass.getName());
+        assertEquals("Example executable template.", templateClass.getDocumentation());
+        templateMethod = templateClass.getExecuteMethod();
+        assertNotNull(templateMethod);
+        assertEquals("execute", templateMethod.getName());
+        assertEquals("It executes.", templateMethod.getDocumentation());
+        parameters = new ArrayList<TemplateParameter>(templateMethod.getParameters());
+        assertEquals(3, parameters.size());
+        parameter = parameters.get(0);
+        assertEquals("one", parameter.getName());
+        assertEquals("java.lang.String", parameter.getType());
+        assertEquals("Parameter one.", parameter.getDocumentation());
+        parameter = parameters.get(1);
+        assertEquals("two", parameter.getName());
+        assertEquals("int", parameter.getType());
+        assertEquals("Parameter two.", parameter.getDocumentation());
+        parameter = parameters.get(2);
+        assertEquals("request", parameter.getName());
+        assertEquals(REQUEST_CLASS, parameter.getType());
+        assertEquals("The request.", parameter.getDocumentation());
+
+        assertNull(suite.getTemplateClassByName(NotFeasibleExampleModel.class.getName()));
+    }
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/core/internal/AnnotatedExampleModel.java b/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/core/internal/AnnotatedExampleModel.java
new file mode 100644
index 000000000..b8d4ea382
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/core/internal/AnnotatedExampleModel.java
@@ -0,0 +1,46 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.core.internal;
+
+import org.apache.tiles.autotag.core.runtime.ModelBody;
+import org.apache.tiles.autotag.core.runtime.annotation.Parameter;
+
+/**
+ * Example start/stop template.
+ *
+ * @version $Rev$ $Date$
+ */
+public class AnnotatedExampleModel {
+
+    /**
+     * It starts.
+     *
+     * @param one Parameter one.
+     * @param two Parameter two.
+     * @param request The request.
+     * @param modelBody The model body.
+     */
+    public void execute(
+            @Parameter(defaultValue = "hello", name = "alternateOne", required = true) String one,
+            int two, ExampleRequest request, ModelBody modelBody) {
+        // Does nothing.
+    }
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/core/internal/ExampleExcluded.java b/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/core/internal/ExampleExcluded.java
new file mode 100644
index 000000000..4f53b83b0
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/core/internal/ExampleExcluded.java
@@ -0,0 +1,43 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.core.internal;
+
+import org.apache.tiles.autotag.core.runtime.ModelBody;
+
+/**
+ * Example start/stop template.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ExampleExcluded {
+
+    /**
+     * It starts.
+     *
+     * @param one Parameter one.
+     * @param two Parameter two.
+     * @param request The request.
+     * @param modelBody The model body.
+     */
+    public void execute(String one, int two, ExampleRequest request, ModelBody modelBody) {
+        // Does nothing.
+    }
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/core/internal/ExampleExecutableModel.java b/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/core/internal/ExampleExecutableModel.java
new file mode 100644
index 000000000..661e8ca60
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/core/internal/ExampleExecutableModel.java
@@ -0,0 +1,40 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.core.internal;
+
+/**
+ * Example executable template.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ExampleExecutableModel {
+
+    /**
+     * It executes.
+     *
+     * @param one Parameter one.
+     * @param two Parameter two.
+     * @param request The request.
+     */
+    public void execute(String one, int two, ExampleRequest request) {
+        // Does nothing.
+    }
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/core/internal/ExampleModel.java b/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/core/internal/ExampleModel.java
new file mode 100644
index 000000000..0f68fd6b3
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/core/internal/ExampleModel.java
@@ -0,0 +1,43 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.core.internal;
+
+import org.apache.tiles.autotag.core.runtime.ModelBody;
+
+/**
+ * Example start/stop template.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ExampleModel {
+
+    /**
+     * It starts.
+     *
+     * @param one Parameter one.
+     * @param two Parameter two.
+     * @param request The request.
+     * @param modelBody The model body.
+     */
+    public void execute(String one, int two, ExampleRequest request, ModelBody modelBody) {
+        // Does nothing.
+    }
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/core/internal/ExampleRequest.java b/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/core/internal/ExampleRequest.java
new file mode 100644
index 000000000..620db4321
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/core/internal/ExampleRequest.java
@@ -0,0 +1,25 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.core.internal;
+
+public class ExampleRequest {
+
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/core/internal/NotFeasibleExampleModel.java b/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/core/internal/NotFeasibleExampleModel.java
new file mode 100644
index 000000000..44dc258a7
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/core/internal/NotFeasibleExampleModel.java
@@ -0,0 +1,38 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.core.internal;
+
+/**
+ * This won't be registered.
+ *
+ * @version $Rev$ $Date$
+ */
+public class NotFeasibleExampleModel {
+
+    /**
+     * It starts.
+     *
+     * @param whatever Doesn't matter.
+     */
+    public void start(String whatever) {
+        // Does nothing.
+    }
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/generate/AbstractTemplateClassGeneratorTest.java b/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/generate/AbstractTemplateClassGeneratorTest.java
new file mode 100644
index 000000000..b05ff31fd
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/generate/AbstractTemplateClassGeneratorTest.java
@@ -0,0 +1,279 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.generate;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.createMockBuilder;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.isA;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Map;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.tiles.autotag.core.AutotagRuntimeException;
+import org.apache.tiles.autotag.core.ClassParseException;
+import org.apache.tiles.autotag.core.OutputLocator;
+import org.apache.tiles.autotag.core.DirectoryOutputLocator;
+import org.apache.tiles.autotag.model.TemplateClass;
+import org.apache.tiles.autotag.model.TemplateSuite;
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
+import org.apache.velocity.exception.ParseErrorException;
+import org.apache.velocity.exception.ResourceNotFoundException;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests {@link AbstractTemplateClassGenerator}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class AbstractTemplateClassGeneratorTest {
+
+    /**
+     * The velocity engine.
+     */
+    private VelocityEngine velocityEngine;
+
+    /**
+     * The temporary directory.
+     */
+    private File directory;
+
+    /**
+     * The generator to test.
+     */
+    private AbstractTemplateClassGenerator generator;
+
+    /**
+     * Sets up the test.
+     *
+     * @throws IOException If something goes wrong.
+     */
+    @Before
+    public void setUp() throws IOException {
+        velocityEngine = createMock(VelocityEngine.class);
+        generator = createMockBuilder(AbstractTemplateClassGenerator.class)
+                .withConstructor(velocityEngine).createMock();
+        directory = File.createTempFile("autotag", null);
+    }
+
+    /**
+     * Tears down the test.
+     *
+     * @throws IOException If something goes wrong.
+     */
+    public void tearDown() throws IOException {
+        FileUtils.deleteDirectory(directory);
+    }
+
+    /**
+     * Test method for {@link AbstractTemplateClassGenerator#generate(java.io.File,
+     * String, TemplateSuite, TemplateClass, Map)}.
+     * @throws Exception If something goes wrong.
+     */
+    @Test
+    public void testGenerate() throws Exception {
+        directory.delete();
+        directory.mkdir();
+        OutputLocator locator = new DirectoryOutputLocator(directory);
+        TemplateSuite suite = createMock(TemplateSuite.class);
+        TemplateClass clazz = createMock(TemplateClass.class);
+        Template template = createMock(Template.class);
+        @SuppressWarnings("unchecked")
+        Map<String, String> parameters = createMock(Map.class);
+        String packageName = "org.apache.tiles.autotag.test";
+        String runtimeClass = "org.apache.tiles.autotag.test.DoStuffRuntime";
+        String requestClass = "org.apache.tiles.autotag.test.DoStuffRequest";
+
+        expect(generator.getDirectoryName(packageName, suite, clazz, parameters, runtimeClass, requestClass)).andReturn("mydir");
+        expect(generator.getFilename(packageName, suite, clazz, parameters, runtimeClass, requestClass)).andReturn("myfile.txt");
+        String sampleVmPath = "/sample.vm";
+        expect(generator.getTemplatePath(packageName, suite, clazz, parameters, runtimeClass, requestClass)).andReturn(sampleVmPath);
+        expect(velocityEngine.getTemplate("/sample.vm")).andReturn(template);
+        template.merge(isA(VelocityContext.class), isA(Writer.class));
+
+        replay(velocityEngine, generator, suite, clazz, template, parameters);
+        generator.generate(locator, packageName, suite, clazz, parameters, runtimeClass, requestClass);
+        verify(velocityEngine, generator, suite, clazz, template, parameters);
+    }
+
+    /**
+     * Test method for {@link AbstractTemplateClassGenerator#generate(File, String, TemplateSuite, TemplateClass, Map)}.
+     * @throws Exception If something goes wrong.
+     */
+    @Test(expected = AutotagRuntimeException.class)
+    public void testGenerateException1() throws Exception {
+        directory.delete();
+        directory.mkdir();
+        OutputLocator locator = new DirectoryOutputLocator(directory);
+        TemplateSuite suite = createMock(TemplateSuite.class);
+        TemplateClass clazz = createMock(TemplateClass.class);
+        Template template = createMock(Template.class);
+        @SuppressWarnings("unchecked")
+        Map<String, String> parameters = createMock(Map.class);
+        String packageName = "org.apache.tiles.autotag.test";
+        String runtimeClass = "org.apache.tiles.autotag.test.DoStuffRuntime";
+        String requestClass = "org.apache.tiles.autotag.test.DoStuffRequest";
+
+        expect(generator.getDirectoryName(packageName, suite, clazz, parameters, runtimeClass, requestClass)).andReturn("mydir");
+        expect(generator.getFilename(packageName, suite, clazz, parameters, runtimeClass, requestClass)).andReturn("myfile.txt");
+        String sampleVmPath = "/sample.vm";
+        expect(generator.getTemplatePath(packageName, suite, clazz, parameters, runtimeClass, requestClass)).andReturn(sampleVmPath);
+        expect(velocityEngine.getTemplate("/sample.vm")).andThrow(new ResourceNotFoundException("hello"));
+
+        replay(velocityEngine, generator, suite, clazz, template, parameters);
+        generator.generate(locator, packageName, suite, clazz, parameters, runtimeClass, requestClass);
+        verify(velocityEngine, generator, suite, clazz, template, parameters);
+    }
+
+    /**
+     * Test method for {@link AbstractTemplateClassGenerator#generate(File, String, TemplateSuite, TemplateClass, Map)}.
+     * @throws Exception If something goes wrong.
+     */
+    @Test(expected = AutotagRuntimeException.class)
+    public void testGenerateException2() throws Exception {
+        directory.delete();
+        directory.mkdir();
+        OutputLocator locator = new DirectoryOutputLocator(directory);
+        TemplateSuite suite = createMock(TemplateSuite.class);
+        TemplateClass clazz = createMock(TemplateClass.class);
+        Template template = createMock(Template.class);
+        @SuppressWarnings("unchecked")
+        Map<String, String> parameters = createMock(Map.class);
+        String packageName = "org.apache.tiles.autotag.test";
+        String runtimeClass = "org.apache.tiles.autotag.test.DoStuffRuntime";
+        String requestClass = "org.apache.tiles.autotag.test.DoStuffRequest";
+
+        expect(generator.getDirectoryName(packageName, suite, clazz, parameters, runtimeClass, requestClass)).andReturn("mydir");
+        expect(generator.getFilename(packageName, suite, clazz, parameters, runtimeClass, requestClass)).andReturn("myfile.txt");
+        String sampleVmPath = "/sample.vm";
+        expect(generator.getTemplatePath(packageName, suite, clazz, parameters, runtimeClass, requestClass)).andReturn(sampleVmPath);
+        expect(velocityEngine.getTemplate("/sample.vm")).andThrow(new ParseErrorException("hello"));
+
+        replay(velocityEngine, generator, suite, clazz, template, parameters);
+        generator.generate(locator, packageName, suite, clazz, parameters, runtimeClass, requestClass);
+        verify(velocityEngine, generator, suite, clazz, template, parameters);
+    }
+
+    /**
+     * Test method for {@link AbstractTemplateClassGenerator#generate(File, String, TemplateSuite, TemplateClass, Map)}.
+     * @throws Exception If something goes wrong.
+     */
+    @Test(expected = AutotagRuntimeException.class)
+    public void testGenerateException3() throws Exception {
+        directory.delete();
+        directory.mkdir();
+        OutputLocator locator = new DirectoryOutputLocator(directory);
+        TemplateSuite suite = createMock(TemplateSuite.class);
+        TemplateClass clazz = createMock(TemplateClass.class);
+        Template template = createMock(Template.class);
+        @SuppressWarnings("unchecked")
+        Map<String, String> parameters = createMock(Map.class);
+        String packageName = "org.apache.tiles.autotag.test";
+        String runtimeClass = "org.apache.tiles.autotag.test.DoStuffRuntime";
+        String requestClass = "org.apache.tiles.autotag.test.DoStuffRequest";
+
+        expect(generator.getDirectoryName(packageName, suite, clazz, parameters, runtimeClass, requestClass)).andReturn("mydir");
+        expect(generator.getFilename(packageName, suite, clazz, parameters, runtimeClass, requestClass)).andReturn("myfile.txt");
+        String sampleVmPath = "/sample.vm";
+        expect(generator.getTemplatePath(packageName, suite, clazz, parameters, runtimeClass, requestClass)).andReturn(sampleVmPath);
+        expect(velocityEngine.getTemplate("/sample.vm")).andThrow(new Exception());
+
+        replay(velocityEngine, generator, suite, clazz, template, parameters);
+        generator.generate(locator, packageName, suite, clazz, parameters, runtimeClass, requestClass);
+        verify(velocityEngine, generator, suite, clazz, template, parameters);
+    }
+
+    /**
+     * Test method for {@link AbstractTemplateClassGenerator#generate(File, String, TemplateSuite, TemplateClass, Map)}.
+     * @throws Exception If something goes wrong.
+     * @throws ParseErrorException If something goes wrong.
+     * @throws ResourceNotFoundException If something goes wrong.
+     */
+    @Test(expected = AutotagRuntimeException.class)
+    public void testGenerateException4() throws Exception {
+        directory.delete();
+        directory.mkdir();
+        OutputLocator locator = new DirectoryOutputLocator(directory);
+        TemplateSuite suite = createMock(TemplateSuite.class);
+        TemplateClass clazz = createMock(TemplateClass.class);
+        Template template = createMock(Template.class);
+        @SuppressWarnings("unchecked")
+        Map<String, String> parameters = createMock(Map.class);
+        String packageName = "org.apache.tiles.autotag.test";
+        String runtimeClass = "org.apache.tiles.autotag.test.DoStuffRuntime";
+        String requestClass = "org.apache.tiles.autotag.test.DoStuffRequest";
+
+        expect(generator.getDirectoryName(packageName, suite, clazz, parameters, runtimeClass, requestClass)).andReturn("mydir");
+        expect(generator.getFilename(packageName, suite, clazz, parameters, runtimeClass, requestClass)).andReturn("myfile.txt");
+        String sampleVmPath = "/sample.vm";
+        expect(generator.getTemplatePath(packageName, suite, clazz, parameters, runtimeClass, requestClass)).andReturn(sampleVmPath);
+        expect(velocityEngine.getTemplate("/sample.vm")).andReturn(template);
+        template.merge(isA(VelocityContext.class), isA(Writer.class));
+        expectLastCall().andThrow(new IOException());
+
+        replay(velocityEngine, generator, suite, clazz, template, parameters);
+        generator.generate(locator, packageName, suite, clazz, parameters, runtimeClass, requestClass);
+        verify(velocityEngine, generator, suite, clazz, template, parameters);
+    }
+
+    /**
+     * Test method for {@link AbstractTemplateClassGenerator#generate(File, String, TemplateSuite, TemplateClass, Map)}.
+     * @throws Exception If something goes wrong.
+     * @throws ParseErrorException If something goes wrong.
+     * @throws ResourceNotFoundException If something goes wrong.
+     */
+    @Test(expected = ClassParseException.class)
+    public void testGenerateException5() throws Exception {
+        directory.delete();
+        directory.mkdir();
+        OutputLocator locator = new DirectoryOutputLocator(directory);
+        TemplateSuite suite = createMock(TemplateSuite.class);
+        TemplateClass clazz = createMock(TemplateClass.class);
+        Template template = createMock(Template.class);
+        @SuppressWarnings("unchecked")
+        Map<String, String> parameters = createMock(Map.class);
+        String packageName = "org.apache.tiles.autotag.test";
+        String runtimeClass = "org.apache.tiles.autotag.test.DoStuffRuntime";
+        String requestClass = "org.apache.tiles.autotag.test.DoStuffRequest";
+
+        expect(generator.getDirectoryName(packageName, suite, clazz, parameters, runtimeClass, requestClass)).andReturn("mydir");
+        expect(generator.getFilename(packageName, suite, clazz, parameters, runtimeClass, requestClass)).andReturn("myfile.txt");
+        String sampleVmPath = "/sample.vm";
+        expect(generator.getTemplatePath(packageName, suite, clazz, parameters, runtimeClass, requestClass)).andReturn(sampleVmPath);
+        expect(velocityEngine.getTemplate("/sample.vm")).andReturn(template);
+        template.merge(isA(VelocityContext.class), isA(Writer.class));
+        expectLastCall().andThrow(new ClassParseException());
+
+        replay(velocityEngine, generator, suite, clazz, template, parameters);
+        generator.generate(locator, packageName, suite, clazz, parameters, runtimeClass, requestClass);
+        verify(velocityEngine, generator, suite, clazz, template, parameters);
+    }
+
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/generate/AbstractTemplateSuiteGeneratorTest.java b/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/generate/AbstractTemplateSuiteGeneratorTest.java
new file mode 100644
index 000000000..b89ea76dc
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/generate/AbstractTemplateSuiteGeneratorTest.java
@@ -0,0 +1,267 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.generate;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.createMockBuilder;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.isA;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Map;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.tiles.autotag.core.AutotagRuntimeException;
+import org.apache.tiles.autotag.core.ClassParseException;
+import org.apache.tiles.autotag.core.OutputLocator;
+import org.apache.tiles.autotag.core.DirectoryOutputLocator;
+import org.apache.tiles.autotag.model.TemplateSuite;
+import org.apache.velocity.Template;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
+import org.apache.velocity.exception.ParseErrorException;
+import org.apache.velocity.exception.ResourceNotFoundException;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests {@link AbstractTemplateSuiteGenerator}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class AbstractTemplateSuiteGeneratorTest {
+
+    /**
+     * The velocity engine.
+     */
+    private VelocityEngine velocityEngine;
+
+    /**
+     * The temporary directory.
+     */
+    private File directory;
+
+    /**
+     * The generator to test.
+     */
+    private AbstractTemplateSuiteGenerator generator;
+
+    /**
+     * Sets up the test.
+     *
+     * @throws IOException If something goes wrong.
+     */
+    @Before
+    public void setUp() throws IOException {
+        velocityEngine = createMock(VelocityEngine.class);
+        generator = createMockBuilder(AbstractTemplateSuiteGenerator.class)
+                .withConstructor(velocityEngine).createMock();
+        directory = File.createTempFile("autotag", null);
+    }
+
+    /**
+     * Tears down the test.
+     *
+     * @throws IOException If something goes wrong.
+     */
+    public void tearDown() throws IOException {
+        FileUtils.deleteDirectory(directory);
+    }
+
+    /**
+     * Test method for {@link AbstractTemplateSuiteGenerator#generate(File, String, TemplateSuite, Map)}.
+     * @throws Exception If something goes wrong.
+     * @throws ParseErrorException If something goes wrong.
+     * @throws ResourceNotFoundException If something goes wrong.
+     */
+    @Test
+    public void testGenerate() throws Exception {
+        directory.delete();
+        directory.mkdir();
+        OutputLocator locator = new DirectoryOutputLocator(directory);
+        TemplateSuite suite = createMock(TemplateSuite.class);
+        Template template = createMock(Template.class);
+        @SuppressWarnings("unchecked")
+        Map<String, String> parameters = createMock(Map.class);
+        String packageName = "org.apache.tiles.autotag.test";
+
+        expect(generator.getDirectoryName(packageName, suite, parameters)).andReturn("mydir");
+        expect(generator.getFilename(packageName, suite, parameters)).andReturn("myfile.txt");
+        String sampleVmPath = "/sample.vm";
+        expect(generator.getTemplatePath(packageName, suite, parameters)).andReturn(sampleVmPath);
+        expect(velocityEngine.getTemplate("/sample.vm")).andReturn(template);
+        template.merge(isA(VelocityContext.class), isA(Writer.class));
+
+        replay(velocityEngine, generator, suite, template, parameters);
+        generator.generate(locator, packageName, suite, parameters);
+        verify(velocityEngine, generator, suite, template, parameters);
+    }
+
+    /**
+     * Test method for {@link AbstractTemplateSuiteGenerator#generate(File, String, TemplateSuite, Map)}.
+     * @throws Exception If something goes wrong.
+     * @throws ParseErrorException If something goes wrong.
+     * @throws ResourceNotFoundException If something goes wrong.
+     */
+    @Test(expected = AutotagRuntimeException.class)
+    public void testGenerateException1() throws Exception {
+        directory.delete();
+        directory.mkdir();
+        OutputLocator locator = new DirectoryOutputLocator(directory);
+        TemplateSuite suite = createMock(TemplateSuite.class);
+        Template template = createMock(Template.class);
+        @SuppressWarnings("unchecked")
+        Map<String, String> parameters = createMock(Map.class);
+        String packageName = "org.apache.tiles.autotag.test";
+
+        expect(generator.getDirectoryName(packageName, suite, parameters)).andReturn("mydir");
+        expect(generator.getFilename(packageName, suite, parameters)).andReturn("myfile.txt");
+        String sampleVmPath = "/sample.vm";
+        expect(generator.getTemplatePath(packageName, suite, parameters)).andReturn(sampleVmPath);
+        expect(velocityEngine.getTemplate("/sample.vm")).andThrow(new ResourceNotFoundException("hello"));
+
+        replay(velocityEngine, generator, suite, template, parameters);
+        generator.generate(locator, packageName, suite, parameters);
+        verify(velocityEngine, generator, suite, template, parameters);
+    }
+
+    /**
+     * Test method for {@link AbstractTemplateSuiteGenerator#generate(File, String, TemplateSuite, Map)}.
+     * @throws Exception If something goes wrong.
+     * @throws ParseErrorException If something goes wrong.
+     * @throws ResourceNotFoundException If something goes wrong.
+     */
+    @Test(expected = AutotagRuntimeException.class)
+    public void testGenerateException2() throws Exception {
+        directory.delete();
+        directory.mkdir();
+        OutputLocator locator = new DirectoryOutputLocator(directory);
+        TemplateSuite suite = createMock(TemplateSuite.class);
+        Template template = createMock(Template.class);
+        @SuppressWarnings("unchecked")
+        Map<String, String> parameters = createMock(Map.class);
+        String packageName = "org.apache.tiles.autotag.test";
+
+        expect(generator.getDirectoryName(packageName, suite, parameters)).andReturn("mydir");
+        expect(generator.getFilename(packageName, suite, parameters)).andReturn("myfile.txt");
+        String sampleVmPath = "/sample.vm";
+        expect(generator.getTemplatePath(packageName, suite, parameters)).andReturn(sampleVmPath);
+        expect(velocityEngine.getTemplate("/sample.vm")).andThrow(new ParseErrorException("hello"));
+
+        replay(velocityEngine, generator, suite, template, parameters);
+        generator.generate(locator, packageName, suite, parameters);
+        verify(velocityEngine, generator, suite, template, parameters);
+    }
+
+    /**
+     * Test method for {@link AbstractTemplateSuiteGenerator#generate(File, String, TemplateSuite, Map)}.
+     * @throws Exception If something goes wrong.
+     * @throws ParseErrorException If something goes wrong.
+     * @throws ResourceNotFoundException If something goes wrong.
+     */
+    @Test(expected = AutotagRuntimeException.class)
+    public void testGenerateException3() throws Exception {
+        directory.delete();
+        directory.mkdir();
+        OutputLocator locator = new DirectoryOutputLocator(directory);
+        TemplateSuite suite = createMock(TemplateSuite.class);
+        Template template = createMock(Template.class);
+        @SuppressWarnings("unchecked")
+        Map<String, String> parameters = createMock(Map.class);
+        String packageName = "org.apache.tiles.autotag.test";
+
+        expect(generator.getDirectoryName(packageName, suite, parameters)).andReturn("mydir");
+        expect(generator.getFilename(packageName, suite, parameters)).andReturn("myfile.txt");
+        String sampleVmPath = "/sample.vm";
+        expect(generator.getTemplatePath(packageName, suite, parameters)).andReturn(sampleVmPath);
+        expect(velocityEngine.getTemplate("/sample.vm")).andThrow(new Exception());
+
+        replay(velocityEngine, generator, suite, template, parameters);
+        generator.generate(locator, packageName, suite, parameters);
+        verify(velocityEngine, generator, suite, template, parameters);
+    }
+
+    /**
+     * Test method for {@link AbstractTemplateSuiteGenerator#generate(File, String, TemplateSuite, Map)}.
+     * @throws Exception If something goes wrong.
+     * @throws ParseErrorException If something goes wrong.
+     * @throws ResourceNotFoundException If something goes wrong.
+     */
+    @Test(expected = AutotagRuntimeException.class)
+    public void testGenerateException4() throws Exception {
+        directory.delete();
+        directory.mkdir();
+        OutputLocator locator = new DirectoryOutputLocator(directory);
+        TemplateSuite suite = createMock(TemplateSuite.class);
+        Template template = createMock(Template.class);
+        @SuppressWarnings("unchecked")
+        Map<String, String> parameters = createMock(Map.class);
+        String packageName = "org.apache.tiles.autotag.test";
+
+        expect(generator.getDirectoryName(packageName, suite, parameters)).andReturn("mydir");
+        expect(generator.getFilename(packageName, suite, parameters)).andReturn("myfile.txt");
+        String sampleVmPath = "/sample.vm";
+        expect(generator.getTemplatePath(packageName, suite, parameters)).andReturn(sampleVmPath);
+        expect(velocityEngine.getTemplate("/sample.vm")).andReturn(template);
+        template.merge(isA(VelocityContext.class), isA(Writer.class));
+        expectLastCall().andThrow(new IOException());
+
+        replay(velocityEngine, generator, suite, template, parameters);
+        generator.generate(locator, packageName, suite, parameters);
+        verify(velocityEngine, generator, suite, template, parameters);
+    }
+
+    /**
+     * Test method for {@link AbstractTemplateSuiteGenerator#generate(File, String, TemplateSuite, Map)}.
+     * @throws Exception If something goes wrong.
+     * @throws ParseErrorException If something goes wrong.
+     * @throws ResourceNotFoundException If something goes wrong.
+     */
+    @Test(expected = ClassParseException.class)
+    public void testGenerateException5() throws Exception {
+        directory.delete();
+        directory.mkdir();
+        OutputLocator locator = new DirectoryOutputLocator(directory);
+        TemplateSuite suite = createMock(TemplateSuite.class);
+        Template template = createMock(Template.class);
+        @SuppressWarnings("unchecked")
+        Map<String, String> parameters = createMock(Map.class);
+        String packageName = "org.apache.tiles.autotag.test";
+
+        expect(generator.getDirectoryName(packageName, suite, parameters)).andReturn("mydir");
+        expect(generator.getFilename(packageName, suite, parameters)).andReturn("myfile.txt");
+        String sampleVmPath = "/sample.vm";
+        expect(generator.getTemplatePath(packageName, suite, parameters)).andReturn(sampleVmPath);
+        expect(velocityEngine.getTemplate("/sample.vm")).andReturn(template);
+        template.merge(isA(VelocityContext.class), isA(Writer.class));
+        expectLastCall().andThrow(new ClassParseException());
+
+        replay(velocityEngine, generator, suite, template, parameters);
+        generator.generate(locator, packageName, suite, parameters);
+        verify(velocityEngine, generator, suite, template, parameters);
+    }
+
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/generate/BasicTemplateGeneratorTest.java b/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/generate/BasicTemplateGeneratorTest.java
new file mode 100644
index 000000000..0837d83e3
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/generate/BasicTemplateGeneratorTest.java
@@ -0,0 +1,83 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.generate;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tiles.autotag.core.OutputLocator;
+import org.apache.tiles.autotag.generate.BasicTemplateGenerator.TCGeneratorDirectoryPair;
+import org.apache.tiles.autotag.generate.BasicTemplateGenerator.TSGeneratorDirectoryPair;
+import org.apache.tiles.autotag.model.TemplateClass;
+import org.apache.tiles.autotag.model.TemplateSuite;
+import org.junit.Test;
+
+/**
+ * Tests {@link BasicTemplateGenerator}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class BasicTemplateGeneratorTest {
+
+    /**
+     * Test method for {@link BasicTemplateGenerator#generate(String, TemplateSuite, Map)}.
+     * @throws IOException If something goes wrong.
+     */
+    @Test
+    public void testGenerate() throws IOException {
+    	OutputLocator locator = createMock(OutputLocator.class);
+        TemplateSuite suite = createMock(TemplateSuite.class);
+        TemplateClass templateClass = createMock(TemplateClass.class);
+        TemplateSuiteGenerator templateSuiteGenerator = createMock(TemplateSuiteGenerator.class);
+        TemplateClassGenerator templateClassGenerator = createMock(TemplateClassGenerator.class);
+        @SuppressWarnings("unchecked")
+        Map<String, String> parameters = createMock(Map.class);
+        List<TemplateClass> templateClasses = new ArrayList<TemplateClass>();
+
+        templateClasses.add(templateClass);
+
+        expect(suite.getTemplateClasses()).andReturn(templateClasses);
+        templateSuiteGenerator.generate(locator, "my.package", suite, parameters);
+        templateClassGenerator.generate(locator, "my.package", suite, templateClass, parameters, "my.Runtime", "my.Request");
+
+        replay(suite, templateClass, templateSuiteGenerator, templateClassGenerator, parameters);
+        TSGeneratorDirectoryPair tsPair = new TSGeneratorDirectoryPair(locator, templateSuiteGenerator);
+        TCGeneratorDirectoryPair tcPair = new TCGeneratorDirectoryPair(locator, templateClassGenerator);
+        List<TSGeneratorDirectoryPair> tsList = new ArrayList<BasicTemplateGenerator.TSGeneratorDirectoryPair>();
+        tsList.add(tsPair);
+        List<TCGeneratorDirectoryPair> tcList = new ArrayList<BasicTemplateGenerator.TCGeneratorDirectoryPair>();
+        tcList.add(tcPair);
+        BasicTemplateGenerator generator = new BasicTemplateGenerator(tsList, tcList, true, false);
+        assertTrue(generator.isGeneratingClasses());
+        assertFalse(generator.isGeneratingResources());
+        generator.generate("my.package", suite, parameters, "my.Runtime", "my.Request");
+        verify(suite, templateClass, templateSuiteGenerator, templateClassGenerator, parameters);
+    }
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/generate/TemplateGeneratorBuilderTest.java b/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/generate/TemplateGeneratorBuilderTest.java
new file mode 100644
index 000000000..e3c02e2b8
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/generate/TemplateGeneratorBuilderTest.java
@@ -0,0 +1,171 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.generate;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.apache.tiles.autotag.core.OutputLocator;
+import org.junit.Test;
+
+/**
+ * @author antonio
+ *
+ * @version $Rev$ $Date$
+ */
+public class TemplateGeneratorBuilderTest {
+
+    /**
+     * Test method for {@link TemplateGeneratorBuilder#addClassesTemplateSuiteGenerator(TemplateSuiteGenerator)}.
+     */
+    @Test
+    public void testAddClassesTemplateSuiteGenerator() {
+        OutputLocator locator = createMock(OutputLocator.class);
+        TemplateSuiteGenerator generator = createMock(TemplateSuiteGenerator.class);
+
+        replay(locator, generator);
+        TemplateGenerator templateGenerator = TemplateGeneratorBuilder
+                .createNewInstance().setClassesOutputLocator(locator)
+                .addClassesTemplateSuiteGenerator(generator).build();
+        assertTrue(templateGenerator.isGeneratingClasses());
+        assertFalse(templateGenerator.isGeneratingResources());
+        verify(locator, generator);
+    }
+
+    /**
+     * Test method for {@link TemplateGeneratorBuilder#addClassesTemplateSuiteGenerator(TemplateSuiteGenerator)}.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testAddClassesTemplateSuiteGeneratorException() {
+        TemplateSuiteGenerator generator = createMock(TemplateSuiteGenerator.class);
+
+        replay(generator);
+        try {
+            TemplateGeneratorBuilder.createNewInstance()
+                    .addClassesTemplateSuiteGenerator(generator);
+        } finally {
+            verify(generator);
+        }
+    }
+
+    /**
+     * Test method for {@link TemplateGeneratorBuilder#addClassesTemplateClassGenerator(TemplateClassGenerator)}.
+     */
+    @Test
+    public void testAddClassesTemplateClassGenerator() {
+        OutputLocator locator = createMock(OutputLocator.class);
+        TemplateClassGenerator generator = createMock(TemplateClassGenerator.class);
+
+        replay(locator, generator);
+        TemplateGenerator templateGenerator = TemplateGeneratorBuilder
+                .createNewInstance().setClassesOutputLocator(locator)
+                .addClassesTemplateClassGenerator(generator).build();
+        assertTrue(templateGenerator.isGeneratingClasses());
+        assertFalse(templateGenerator.isGeneratingResources());
+        verify(locator, generator);
+    }
+
+    /**
+     * Test method for {@link TemplateGeneratorBuilder#addClassesTemplateClassGenerator(TemplateClassGenerator)}.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testAddClassesTemplateClassGeneratorException() {
+        TemplateClassGenerator generator = createMock(TemplateClassGenerator.class);
+
+        replay(generator);
+        try {
+            TemplateGeneratorBuilder.createNewInstance()
+                    .addClassesTemplateClassGenerator(generator);
+        } finally {
+            verify(generator);
+        }
+    }
+
+    /**
+     * Test method for {@link TemplateGeneratorBuilder#addResourcesTemplateSuiteGenerator(TemplateSuiteGenerator)}.
+     */
+    @Test
+    public void testAddResourcesTemplateSuiteGenerator() {
+        OutputLocator locator = createMock(OutputLocator.class);
+        TemplateSuiteGenerator generator = createMock(TemplateSuiteGenerator.class);
+
+        replay(locator, generator);
+        TemplateGenerator templateGenerator = TemplateGeneratorBuilder
+                .createNewInstance().setResourcesOutputLocator(locator)
+                .addResourcesTemplateSuiteGenerator(generator).build();
+        assertFalse(templateGenerator.isGeneratingClasses());
+        assertTrue(templateGenerator.isGeneratingResources());
+        verify(locator, generator);
+    }
+
+    /**
+     * Test method for {@link TemplateGeneratorBuilder#addResourcesTemplateSuiteGenerator(TemplateSuiteGenerator)}.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testAddResourcesTemplateSuiteGeneratorException() {
+        TemplateSuiteGenerator generator = createMock(TemplateSuiteGenerator.class);
+
+        replay(generator);
+        try {
+            TemplateGeneratorBuilder.createNewInstance()
+                    .addResourcesTemplateSuiteGenerator(generator);
+        } finally {
+            verify(generator);
+        }
+    }
+
+    /**
+     * Test method for {@link TemplateGeneratorBuilder#addResourcesTemplateClassGenerator(TemplateClassGenerator)}.
+     */
+    @Test
+    public void testAddResourcesTemplateClassGenerator() {
+        OutputLocator locator = createMock(OutputLocator.class);
+        TemplateClassGenerator generator = createMock(TemplateClassGenerator.class);
+
+        replay(locator, generator);
+        TemplateGenerator templateGenerator = TemplateGeneratorBuilder
+                .createNewInstance().setResourcesOutputLocator(locator)
+                .addResourcesTemplateClassGenerator(generator).build();
+        assertFalse(templateGenerator.isGeneratingClasses());
+        assertTrue(templateGenerator.isGeneratingResources());
+        verify(locator, generator);
+    }
+
+    /**
+     * Test method for {@link TemplateGeneratorBuilder#addResourcesTemplateClassGenerator(TemplateClassGenerator)}.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testAddResourcesTemplateClassGeneratorException() {
+        TemplateClassGenerator generator = createMock(TemplateClassGenerator.class);
+
+        replay(generator);
+        try {
+            TemplateGeneratorBuilder.createNewInstance()
+                    .addResourcesTemplateClassGenerator(generator);
+        } finally {
+            verify(generator);
+        }
+    }
+
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/model/TemplateClassTest.java b/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/model/TemplateClassTest.java
new file mode 100644
index 000000000..e2acdb831
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/model/TemplateClassTest.java
@@ -0,0 +1,157 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.model;
+
+import static org.easymock.EasyMock.*;
+import static org.junit.Assert.*;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.junit.Test;
+
+/**
+ * @author antonio
+ *
+ * @version $Rev$ $Date$
+ */
+public class TemplateClassTest {
+
+    /**
+     * Test method for {@link TemplateClass#TemplateClass(String)}.
+     */
+    @Test
+    public void testTemplateConstructor1() {
+        TemplateClass templateClass = new TemplateClass("name");
+        assertEquals("name", templateClass.getName());
+        assertNull(templateClass.getTagName());
+        assertNull(templateClass.getTagClassPrefix());
+        assertNull(templateClass.getExecuteMethod());
+        Collection<TemplateParameter> params = templateClass.getParameters();
+        assertTrue(params.isEmpty());
+    }
+
+    /**
+     * Test method for {@link TemplateClass#TemplateClass(String, String, String, TemplateMethod)}.
+     */
+    @Test
+    public void testTemplateConstructor2() {
+        TemplateMethod method = createMock(TemplateMethod.class);
+
+        replay(method);
+        TemplateClass templateClass = new TemplateClass("name", "tagName", "tagClassPrefix", method);
+        assertEquals("name", templateClass.getName());
+        assertEquals("tagName", templateClass.getTagName());
+        assertEquals("tagClassPrefix", templateClass.getTagClassPrefix());
+        assertEquals(method, templateClass.getExecuteMethod());
+        verify(method);
+    }
+
+    /**
+     * Test method for {@link TemplateClass#getSimpleName()}.
+     */
+    @Test
+    public void testGetSimpleName() {
+        TemplateClass templateClass = new TemplateClass("name");
+        assertEquals("name", templateClass.getSimpleName());
+        templateClass = new TemplateClass("org.whatever.Hello");
+        assertEquals("Hello", templateClass.getSimpleName());
+    }
+
+    /**
+     * Test method for {@link TemplateClass#setDocumentation(String)}.
+     */
+    @Test
+    public void testSetDocumentation() {
+        TemplateClass templateClass = new TemplateClass("name");
+        templateClass.setDocumentation("docs");
+        assertEquals("docs", templateClass.getDocumentation());
+    }
+
+    /**
+     * Test method for {@link TemplateClass#getParameters()}.
+     */
+    @Test
+    public void testGetParameters() {
+        TemplateParameter param1 = createMock(TemplateParameter.class);
+        TemplateParameter param2 = createMock(TemplateParameter.class);
+        TemplateParameter param3 = createMock(TemplateParameter.class);
+        TemplateParameter param4 = createMock(TemplateParameter.class);
+        TemplateMethod method = createMock(TemplateMethod.class);
+        List<TemplateParameter> params = new ArrayList<TemplateParameter>();
+
+        expect(method.getParameters()).andReturn(params);
+        expect(param1.isRequest()).andReturn(true);
+        expect(param2.isRequest()).andReturn(false);
+        expect(param2.isBody()).andReturn(true);
+        expect(param3.isRequest()).andReturn(false);
+        expect(param3.isBody()).andReturn(false);
+        expect(param4.isRequest()).andReturn(false);
+        expect(param4.isBody()).andReturn(false);
+        expect(param3.getName()).andReturn("param1");
+        expect(param4.getName()).andReturn("param2");
+
+        replay(param1, param2, param3, param4, method);
+        params.add(param1);
+        params.add(param2);
+        params.add(param3);
+        params.add(param4);
+
+        TemplateClass templateClass = new TemplateClass("name", "tagName", "tagClassPrefix", method);
+        Collection<TemplateParameter> returnedParams = templateClass.getParameters();
+        Iterator<TemplateParameter> paramIt = returnedParams.iterator();
+        assertSame(param3, paramIt.next());
+        assertSame(param4, paramIt.next());
+        assertFalse(paramIt.hasNext());
+        verify(param1, param2, param3, param4, method);
+    }
+
+    /**
+     * Test method for {@link TemplateClass#hasBody()}.
+     */
+    @Test
+    public void testHasBody() {
+        TemplateMethod method = createMock(TemplateMethod.class);
+        expect(method.hasBody()).andReturn(true);
+
+        replay(method);
+        TemplateClass templateClass = new TemplateClass("name", "tagName", "tagClassPrefix", method);
+        assertTrue(templateClass.hasBody());
+        verify(method);
+    }
+
+    /**
+     * Test method for {@link TemplateClass#toString()}.
+     */
+    @Test
+    public void testToString() {
+        TemplateMethod method = new TemplateMethod("method", new ArrayList<TemplateParameter>());
+        TemplateClass templateClass = new TemplateClass("name", "tagName", "tagClassPrefix", method);
+        assertEquals(
+                "TemplateClass [name=name, tagName=tagName, tagClassPrefix=tagClassPrefix, "
+                        + "documentation=null, executeMethod=TemplateMethod "
+                        + "[name=method, documentation=null, parameters={}]]",
+                templateClass.toString());
+    }
+
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/model/TemplateMethodTest.java b/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/model/TemplateMethodTest.java
new file mode 100644
index 000000000..c868109cc
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/model/TemplateMethodTest.java
@@ -0,0 +1,130 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.model;
+
+import static org.easymock.EasyMock.*;
+import static org.junit.Assert.*;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.junit.Test;
+
+/**
+ * Tests {@link TemplateMethod}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TemplateMethodTest {
+
+    /**
+     * Tests {@link TemplateMethod#TemplateMethod(String, Iterable)}.
+     */
+    @Test
+    public void testTemplateMethod() {
+        TemplateParameter param1 = createMock(TemplateParameter.class);
+        TemplateParameter param2 = createMock(TemplateParameter.class);
+
+        expect(param1.getName()).andReturn("param1");
+        expect(param2.getName()).andReturn("param2");
+
+        replay(param1, param2);
+        List<TemplateParameter> parameters = new ArrayList<TemplateParameter>();
+        parameters.add(param1);
+        parameters.add(param2);
+
+        TemplateMethod method = new TemplateMethod("method", parameters);
+        assertEquals("method", method.getName());
+        Iterator<TemplateParameter> params = method.getParameters().iterator();
+        assertSame(param1, params.next());
+        assertSame(param2, params.next());
+        assertFalse(params.hasNext());
+        assertSame(param1, method.getParameterByName("param1"));
+        assertSame(param2, method.getParameterByName("param2"));
+        verify(param1, param2);
+    }
+
+    /**
+     * Tests {@link TemplateMethod#setDocumentation(String)}.
+     */
+    @Test
+    public void testSetDocumentation() {
+        TemplateMethod method = new TemplateMethod("method", new ArrayList<TemplateParameter>());
+        method.setDocumentation("docs");
+        assertEquals("docs", method.getDocumentation());
+    }
+
+    /**
+     * Tests {@link TemplateMethod#hasBody()}.
+     */
+    @Test
+    public void testHasBody() {
+        TemplateParameter param1 = createMock(TemplateParameter.class);
+        TemplateParameter param2 = createMock(TemplateParameter.class);
+
+        expect(param1.getName()).andReturn("param1");
+        expect(param2.getName()).andReturn("param2");
+        expect(param1.isBody()).andReturn(true);
+
+        replay(param1, param2);
+        List<TemplateParameter> parameters = new ArrayList<TemplateParameter>();
+        parameters.add(param1);
+        parameters.add(param2);
+
+        TemplateMethod method = new TemplateMethod("method", parameters);
+        assertTrue(method.hasBody());
+        verify(param1, param2);
+    }
+
+    /**
+     * Tests {@link TemplateMethod#hasBody()}.
+     */
+    @Test
+    public void testHasBody2() {
+        TemplateParameter param1 = createMock(TemplateParameter.class);
+        TemplateParameter param2 = createMock(TemplateParameter.class);
+
+        expect(param1.getName()).andReturn("param1");
+        expect(param2.getName()).andReturn("param2");
+        expect(param1.isBody()).andReturn(false);
+        expect(param2.isBody()).andReturn(false);
+
+        replay(param1, param2);
+        List<TemplateParameter> parameters = new ArrayList<TemplateParameter>();
+        parameters.add(param1);
+        parameters.add(param2);
+
+        TemplateMethod method = new TemplateMethod("method", parameters);
+        assertFalse(method.hasBody());
+        verify(param1, param2);
+    }
+
+    /**
+     * Tests {@link TemplateMethod#toString()}.
+     */
+    @Test
+    public void testToString() {
+        TemplateMethod method = new TemplateMethod("method", new ArrayList<TemplateParameter>());
+        assertEquals("TemplateMethod [name=method, documentation=null, parameters={}]", method.toString());
+    }
+
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/model/TemplateParameterTest.java b/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/model/TemplateParameterTest.java
new file mode 100644
index 000000000..bb641bd65
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/model/TemplateParameterTest.java
@@ -0,0 +1,93 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.model;
+
+import static org.junit.Assert.*;
+
+import org.apache.tiles.autotag.core.runtime.ModelBody;
+import org.junit.Test;
+
+/**
+ * Tests {@link TemplateParameter}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TemplateParameterTest {
+
+    /**
+     * Tests {@link TemplateParameter#TemplateParameter(String, String, String, String, boolean)}.
+     */
+    @Test
+    public void testTemplateParameter() {
+        TemplateParameter parameter = new TemplateParameter("name", "exportedName", "type", "defaultValue", true, false);
+        assertEquals("name", parameter.getName());
+        assertEquals("exportedName", parameter.getExportedName());
+        assertEquals("type", parameter.getType());
+        assertEquals("defaultValue", parameter.getDefaultValue());
+        assertTrue(parameter.isRequired());
+        assertEquals("ExportedName", parameter.getGetterSetterSuffix());
+        assertFalse(parameter.isBody());
+        assertFalse(parameter.isRequest());
+
+        parameter = new TemplateParameter("name", "exportedName", "my.Request", "defaultValue", false, true);
+        assertEquals("name", parameter.getName());
+        assertEquals("exportedName", parameter.getExportedName());
+        assertEquals("my.Request", parameter.getType());
+        assertEquals("defaultValue", parameter.getDefaultValue());
+        assertFalse(parameter.isRequired());
+        assertEquals("ExportedName", parameter.getGetterSetterSuffix());
+        assertFalse(parameter.isBody());
+        assertTrue(parameter.isRequest());
+
+        parameter = new TemplateParameter("name", "exportedName", ModelBody.class.getName(), "defaultValue", false, false);
+        assertEquals("name", parameter.getName());
+        assertEquals("exportedName", parameter.getExportedName());
+        assertEquals(ModelBody.class.getName(), parameter.getType());
+        assertEquals("defaultValue", parameter.getDefaultValue());
+        assertFalse(parameter.isRequired());
+        assertEquals("ExportedName", parameter.getGetterSetterSuffix());
+        assertTrue(parameter.isBody());
+        assertFalse(parameter.isRequest());
+    }
+
+    /**
+     * Tests {@link TemplateParameter#setDocumentation(String)}.
+     */
+    @Test
+    public void testSetDocumentation() {
+        TemplateParameter parameter = new TemplateParameter("name", "exportedName", "type", "defaultValue", true, false);
+        parameter.setDocumentation("docs");
+        assertEquals("docs", parameter.getDocumentation());
+    }
+
+    /**
+     * Tests {@link TemplateParameter#toString()}.
+     */
+    @Test
+    public void testToString() {
+        TemplateParameter parameter = new TemplateParameter("name", "exportedName", "type", "defaultValue", true, false);
+        assertEquals(
+                "TemplateParameter [name=name, exportedName=exportedName, "
+                        + "documentation=null, type=type, defaultValue=defaultValue, required=true, request=false]",
+                parameter.toString());
+    }
+
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/model/TemplateSuiteTest.java b/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/model/TemplateSuiteTest.java
new file mode 100644
index 000000000..535ee98ae
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/model/TemplateSuiteTest.java
@@ -0,0 +1,113 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.model;
+
+import static org.easymock.EasyMock.*;
+import static org.junit.Assert.*;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.junit.Test;
+
+/**
+ * Tests {@link TemplateSuite}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TemplateSuiteTest {
+
+    /**
+     * Test method for {@link TemplateSuite#TemplateSuite(java.lang.String, java.lang.String)}.
+     */
+    @Test
+    public void testTemplateSuiteCostructor1() {
+        TemplateSuite suite = new TemplateSuite("name", "docs");
+        assertEquals("name", suite.getName());
+        assertEquals("docs", suite.getDocumentation());
+        assertTrue(suite.getTemplateClasses().isEmpty());
+    }
+
+    /**
+     * Test method for {@link TemplateSuite#TemplateSuite(java.lang.String, java.lang.String, java.lang.Iterable)}.
+     */
+    @Test
+    public void testTemplateSuiteConstructor2() {
+        TemplateClass class1 = createMock(TemplateClass.class);
+        TemplateClass class2 = createMock(TemplateClass.class);
+        expect(class1.getName()).andReturn("class1");
+        expect(class2.getName()).andReturn("class2");
+
+        replay(class1, class2);
+        List<TemplateClass> classes = new ArrayList<TemplateClass>();
+        classes.add(class1);
+        classes.add(class2);
+        TemplateSuite suite = new TemplateSuite("name", "docs", classes);
+        assertEquals("name", suite.getName());
+        assertEquals("docs", suite.getDocumentation());
+        Iterator<TemplateClass> clazzes = suite.getTemplateClasses().iterator();
+        assertSame(class1, clazzes.next());
+        assertSame(class2, clazzes.next());
+        assertFalse(clazzes.hasNext());
+        assertSame(class1, suite.getTemplateClassByName("class1"));
+        assertSame(class2, suite.getTemplateClassByName("class2"));
+        verify(class1, class2);
+    }
+
+    /**
+     * Test method for {@link TemplateSuite#addTemplateClass(org.apache.tiles.autotag.model.TemplateClass)}.
+     */
+    @Test
+    public void testAddTemplateClass() {
+        TemplateClass class1 = createMock(TemplateClass.class);
+        TemplateClass class2 = createMock(TemplateClass.class);
+        expect(class1.getName()).andReturn("class1");
+        expect(class2.getName()).andReturn("class2");
+
+        replay(class1, class2);
+        List<TemplateClass> classes = new ArrayList<TemplateClass>();
+        classes.add(class1);
+        classes.add(class2);
+        TemplateSuite suite = new TemplateSuite("name", "docs");
+        assertEquals("name", suite.getName());
+        assertEquals("docs", suite.getDocumentation());
+        assertTrue(suite.getTemplateClasses().isEmpty());
+        suite.addTemplateClass(class1);
+        suite.addTemplateClass(class2);
+        Iterator<TemplateClass> clazzes = suite.getTemplateClasses().iterator();
+        assertSame(class1, clazzes.next());
+        assertSame(class2, clazzes.next());
+        assertFalse(clazzes.hasNext());
+        assertSame(class1, suite.getTemplateClassByName("class1"));
+        assertSame(class2, suite.getTemplateClassByName("class2"));
+        verify(class1, class2);
+    }
+
+    /**
+     * Test method for {@link TemplateSuite#toString()}.
+     */
+    @Test
+    public void testToString() {
+        TemplateSuite suite = new TemplateSuite("name", "docs");
+        assertEquals("TemplateSuite [name=name, documentation=docs, templateClasses={}]", suite.toString());
+    }
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/tool/StringToolTest.java b/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/tool/StringToolTest.java
new file mode 100644
index 000000000..7fd602334
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-core/src/test/java/org/apache/tiles/autotag/tool/StringToolTest.java
@@ -0,0 +1,82 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.tool;
+
+import static org.junit.Assert.*;
+
+import java.util.List;
+
+import org.junit.Test;
+
+/**
+ * Tests {@link StringTool}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class StringToolTest {
+
+    /**
+     * Test method for {@link org.apache.tiles.autotag.tool.StringTool#splitOnNewlines(java.lang.String)}.
+     */
+    @Test
+    public void testSplitOnNewlines() {
+        StringTool tool = new StringTool();
+        List<String> splitted = tool.splitOnNewlines("time\nto\nsplit");
+        assertEquals(3, splitted.size());
+        assertEquals("time", splitted.get(0));
+        assertEquals("to", splitted.get(1));
+        assertEquals("split", splitted.get(2));
+        splitted = tool.splitOnNewlines(null);
+        assertTrue(splitted.isEmpty());
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.autotag.tool.StringTool#capitalizeFirstLetter(java.lang.String)}.
+     */
+    @Test
+    public void testCapitalizeFirstLetter() {
+        StringTool tool = new StringTool();
+        assertEquals("Whatever", tool.capitalizeFirstLetter("whatever"));
+    }
+
+    /**
+     * Test method for {@link StringTool#getDefaultValue(java.lang.String, java.lang.String)}.
+     */
+    @Test
+    public void testGetDefaultValue() {
+        StringTool tool = new StringTool();
+        assertEquals("0", tool.getDefaultValue("byte", null));
+        assertEquals("1", tool.getDefaultValue("byte", "1"));
+        assertEquals("null", tool.getDefaultValue("Whatever", null));
+        assertEquals("thatsit", tool.getDefaultValue("Whatever", "thatsit"));
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.autotag.tool.StringTool#getClassToCast(java.lang.String)}.
+     */
+    @Test
+    public void testGetClassToCast() {
+        StringTool tool = new StringTool();
+        assertEquals(Byte.class.getName(), tool.getClassToCast("byte"));
+        assertEquals("Whatever", tool.getClassToCast("Whatever"));
+    }
+
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-freemarker/pom.xml b/Java-base/tiles-autotag/src/tiles-autotag-freemarker/pom.xml
new file mode 100644
index 000000000..6bbac00e4
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-freemarker/pom.xml
@@ -0,0 +1,59 @@
+<?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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <artifactId>tiles-autotag</artifactId>
+    <groupId>org.apache.tiles</groupId>
+    <version>1.3-SNAPSHOT</version>
+  </parent>
+  <groupId>org.apache.tiles</groupId>
+  <artifactId>tiles-autotag-freemarker</artifactId>
+  <version>1.3-SNAPSHOT</version>
+  <name>Autotag - Freemarker support</name>
+  <description>Generates code for Freemarker support.</description>
+  <properties>
+        <!-- decrease this whenever possible -->
+        <checkstyle.maxAllowedViolations>2</checkstyle.maxAllowedViolations>
+  </properties>
+  <dependencies>
+  	<dependency>
+  		<groupId>org.apache.tiles</groupId>
+  		<artifactId>tiles-autotag-core</artifactId>
+  	</dependency>
+  	<dependency>
+  		<groupId>junit</groupId>
+  		<artifactId>junit</artifactId>
+  		<scope>test</scope>
+  	</dependency>
+  	<dependency>
+  		<groupId>commons-io</groupId>
+  		<artifactId>commons-io</artifactId>
+  		<scope>test</scope>
+  	</dependency>
+  	<dependency>
+  		<groupId>org.easymock</groupId>
+  		<artifactId>easymock</artifactId>
+  		<scope>test</scope>
+  	</dependency>
+  </dependencies>
+</project>
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-freemarker/src/main/java/org/apache/tiles/autotag/freemarker/FMModelGenerator.java b/Java-base/tiles-autotag/src/tiles-autotag-freemarker/src/main/java/org/apache/tiles/autotag/freemarker/FMModelGenerator.java
new file mode 100644
index 000000000..37f94ff5b
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-freemarker/src/main/java/org/apache/tiles/autotag/freemarker/FMModelGenerator.java
@@ -0,0 +1,66 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.freemarker;
+
+import java.util.Map;
+
+import org.apache.tiles.autotag.generate.AbstractTemplateClassGenerator;
+import org.apache.tiles.autotag.model.TemplateClass;
+import org.apache.tiles.autotag.model.TemplateSuite;
+import org.apache.velocity.app.VelocityEngine;
+
+/**
+ * Generates a single Freemarker directive model, given a template class.
+ *
+ * @version $Rev$ $Date$
+ */
+public class FMModelGenerator extends AbstractTemplateClassGenerator {
+
+    /**
+     * Constructor.
+     *
+     * @param velocityEngine The Velocity engine.
+     */
+    public FMModelGenerator(VelocityEngine velocityEngine) {
+        super(velocityEngine);
+    }
+
+    @Override
+    protected String getDirectoryName(String packageName,
+            TemplateSuite suite, TemplateClass clazz, Map<String, String> parameters,
+            String runtimeClass, String requestClass) {
+        return packageName.replaceAll("\\.", "/");
+    }
+
+    @Override
+    protected String getFilename(String packageName,
+            TemplateSuite suite, TemplateClass clazz, Map<String, String> parameters,
+            String runtimeClass, String requestClass) {
+        return clazz.getTagClassPrefix() + "FMModel.java";
+    }
+
+    @Override
+    protected String getTemplatePath(String packageName,
+            TemplateSuite suite, TemplateClass clazz, Map<String, String> parameters,
+            String runtimeClass, String requestClass) {
+        return "/org/apache/tiles/autotag/freemarker/fmModel.vm";
+    }
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-freemarker/src/main/java/org/apache/tiles/autotag/freemarker/FMModelRepositoryGenerator.java b/Java-base/tiles-autotag/src/tiles-autotag-freemarker/src/main/java/org/apache/tiles/autotag/freemarker/FMModelRepositoryGenerator.java
new file mode 100644
index 000000000..0e0015e9e
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-freemarker/src/main/java/org/apache/tiles/autotag/freemarker/FMModelRepositoryGenerator.java
@@ -0,0 +1,64 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.freemarker;
+
+import java.util.Map;
+
+import org.apache.tiles.autotag.generate.AbstractTemplateSuiteGenerator;
+import org.apache.tiles.autotag.model.TemplateSuite;
+import org.apache.velocity.app.VelocityEngine;
+
+/**
+ * Generates the model repository, given the template suite.
+ *
+ * @version $Rev$ $Date$
+ */
+public class FMModelRepositoryGenerator extends AbstractTemplateSuiteGenerator {
+
+    /**
+     * Constructor.
+     *
+     * @param velocityEngine The Velocity engine.
+     */
+    public FMModelRepositoryGenerator(VelocityEngine velocityEngine) {
+        super(velocityEngine);
+    }
+
+    @Override
+    protected String getTemplatePath(String packageName,
+            TemplateSuite suite, Map<String, String> parameters) {
+        return "/org/apache/tiles/autotag/freemarker/repository.vm";
+    }
+
+    @Override
+    protected String getFilename(String packageName,
+            TemplateSuite suite, Map<String, String> parameters) {
+        String name = suite.getName();
+        return name.substring(0, 1).toUpperCase() + name.substring(1) + "FMModelRepository.java";
+    }
+
+    @Override
+    protected String getDirectoryName(String packageName,
+            TemplateSuite suite, Map<String, String> parameters) {
+        return packageName.replaceAll("\\.", "/");
+    }
+
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-freemarker/src/main/java/org/apache/tiles/autotag/freemarker/FMTemplateGeneratorFactory.java b/Java-base/tiles-autotag/src/tiles-autotag-freemarker/src/main/java/org/apache/tiles/autotag/freemarker/FMTemplateGeneratorFactory.java
new file mode 100644
index 000000000..fdcf8301f
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-freemarker/src/main/java/org/apache/tiles/autotag/freemarker/FMTemplateGeneratorFactory.java
@@ -0,0 +1,75 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.freemarker;
+
+import org.apache.tiles.autotag.core.OutputLocator;
+import org.apache.tiles.autotag.generate.TemplateGenerator;
+import org.apache.tiles.autotag.generate.TemplateGeneratorBuilder;
+import org.apache.tiles.autotag.generate.TemplateGeneratorFactory;
+import org.apache.velocity.app.VelocityEngine;
+
+/**
+ * Creates a template generator that generates code for Freemarker.
+ *
+ * @version $Rev$ $Date$
+ */
+public class FMTemplateGeneratorFactory implements TemplateGeneratorFactory {
+
+    /**
+     * Location of the file.
+     */
+    private OutputLocator classesOutputLocator;
+
+    /**
+     * The Velocity engine.
+     */
+    private VelocityEngine velocityEngine;
+
+    /**
+     * The template generator builder.
+     */
+    private TemplateGeneratorBuilder templateGeneratorBuilder;
+
+    /**
+     * Constructor.
+     *
+     * @param classesOutputDirectory Directory where code will be placed.
+     * @param velocityEngine The Velocity engine.
+     * @param templateGeneratorBuilder The template generator builder.
+     */
+    public FMTemplateGeneratorFactory(OutputLocator classesOutputLocator,
+            VelocityEngine velocityEngine, TemplateGeneratorBuilder templateGeneratorBuilder) {
+        this.classesOutputLocator = classesOutputLocator;
+        this.velocityEngine = velocityEngine;
+        this.templateGeneratorBuilder = templateGeneratorBuilder;
+    }
+
+    @Override
+    public TemplateGenerator createTemplateGenerator() {
+        return templateGeneratorBuilder
+                .setClassesOutputLocator(classesOutputLocator)
+                .addClassesTemplateSuiteGenerator(
+                        new FMModelRepositoryGenerator(velocityEngine))
+                .addClassesTemplateClassGenerator(
+                        new FMModelGenerator(velocityEngine)).build();
+    }
+
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-freemarker/src/main/java/org/apache/tiles/autotag/freemarker/package-info.java b/Java-base/tiles-autotag/src/tiles-autotag-freemarker/src/main/java/org/apache/tiles/autotag/freemarker/package-info.java
new file mode 100644
index 000000000..c230fed86
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-freemarker/src/main/java/org/apache/tiles/autotag/freemarker/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * Autotag support for Freemarker.
+ */
+package org.apache.tiles.autotag.freemarker;
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-freemarker/src/main/resources/org/apache/tiles/autotag/freemarker/fmModel.vm b/Java-base/tiles-autotag/src/tiles-autotag-freemarker/src/main/resources/org/apache/tiles/autotag/freemarker/fmModel.vm
new file mode 100644
index 000000000..dc0492171
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-freemarker/src/main/resources/org/apache/tiles/autotag/freemarker/fmModel.vm
@@ -0,0 +1,82 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *#/*
+ * This file was automatically generated by Apache Tiles Autotag.
+ */
+package ${packageName};
+
+import java.io.IOException;
+import java.util.Map;
+
+#if(${clazz.hasBody()})
+import org.apache.tiles.autotag.core.runtime.ModelBody;
+#end
+import org.apache.tiles.autotag.core.runtime.AutotagRuntime;
+
+import freemarker.core.Environment;
+import freemarker.template.TemplateDirectiveBody;
+import freemarker.template.TemplateDirectiveModel;
+import freemarker.template.TemplateException;
+import freemarker.template.TemplateModel;
+
+/**
+#foreach($line in $stringTool.splitOnNewlines(${clazz.documentation}))
+ * ${line}
+#end
+ */
+public class ${clazz.tagClassPrefix}FMModel implements TemplateDirectiveModel {
+
+    /**
+     * The template model.
+     */
+    private ${clazz.name} model;
+
+    /**
+     * Constructor.
+     *
+     * @param model
+     *            The template model.
+     */
+    public ${clazz.tagClassPrefix}FMModel(${clazz.name} model) {
+        this.model = model;
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
+    @Override
+    public void execute(Environment env, @SuppressWarnings("rawtypes") Map params, TemplateModel[] loopVars,
+            TemplateDirectiveBody body) throws TemplateException, IOException {
+        AutotagRuntime<${requestClass}> runtime = new ${runtimeClass}();
+        if (runtime instanceof TemplateDirectiveModel) {
+            ((TemplateDirectiveModel) runtime).execute(env, params, loopVars, body);
+        }
+        ${requestClass} request = runtime.createRequest();
+#if(${clazz.hasBody()})
+        ModelBody modelBody = runtime.createModelBody();
+#end
+        model.execute(
+#foreach($parameter in ${clazz.parameters})
+            runtime.getParameter("${parameter.exportedName}", ${stringTool.getClassToCast(${parameter.type})}.class, $stringTool.getDefaultValue(${parameter.type}, ${parameter.defaultValue})),
+#end
+                request#if(${clazz.hasBody()}), modelBody#end
+
+        );
+    }
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-freemarker/src/main/resources/org/apache/tiles/autotag/freemarker/repository.vm b/Java-base/tiles-autotag/src/tiles-autotag-freemarker/src/main/resources/org/apache/tiles/autotag/freemarker/repository.vm
new file mode 100644
index 000000000..20724c61a
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-freemarker/src/main/resources/org/apache/tiles/autotag/freemarker/repository.vm
@@ -0,0 +1,58 @@
+#*
+ * $Id: tiles-jsp.tld 836180 2009-11-14 14:00:02Z apetrelli $
+ *
+ * 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.
+ *#/*
+ * This file was automatically generated by Apache Tiles Autotag.
+ */
+package ${packageName};
+
+/**
+#foreach($line in $stringTool.splitOnNewlines(${suite.documentation}))
+ * $line
+#end
+ */
+public class $stringTool.capitalizeFirstLetter(${suite.name})FMModelRepository {
+
+#foreach($clazz in ${suite.getTemplateClasses()})
+    /**
+     * The "${clazz.tagName}" directive.
+     */
+    private ${clazz.tagClassPrefix}FMModel ${clazz.tagName};
+
+#end
+    /**
+     * Constructor.
+     */
+    public TilesFMModelRepository() {
+#foreach($clazz in ${suite.getTemplateClasses()})
+        ${clazz.tagName} = new ${clazz.tagClassPrefix}FMModel(new ${clazz.name}());
+#end
+    }
+#foreach($clazz in ${suite.getTemplateClasses()})
+
+    /**
+     * Returns the "${clazz.tagName}" directive.
+     *
+     * @return The "${clazz.tagName}" directive.
+     */
+    public ${clazz.tagClassPrefix}FMModel get$stringTool.capitalizeFirstLetter(${clazz.tagName})() {
+        return ${clazz.tagName};
+    }
+#end
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-freemarker/src/site/site.xml b/Java-base/tiles-autotag/src/tiles-autotag-freemarker/src/site/site.xml
new file mode 100644
index 000000000..0a7d00df4
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-freemarker/src/site/site.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+/*
+ * $Id: site.xml 1081442 2011-03-14 16:21:08Z apetrelli $
+ *
+ * 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.
+ */
+-->
+<project name="Apache - Tiles Autotags">
+    <bannerLeft>
+        <name>Apache Software Foundation</name>
+        <src>http://www.apache.org/images/asf-logo.gif</src>
+        <href>http://www.apache.org</href>
+    </bannerLeft>
+    <bannerRight>
+        <name>Apache Tiles&#8482;</name>
+        <src>http://tiles.apache.org/images/logo.png</src>
+        <href>http://tiles.apache.org</href>
+    </bannerRight>
+    <body>
+
+        <links>
+            <item name="Apache" href="http://www.apache.org" />
+            <item name="Tiles" href="http://tiles.apache.org" />
+        </links>
+
+
+        <menu name="Apache Tiles&#8482;">
+            <item
+                   name="Tiles Home"
+                   href="../../index.html"/>
+            <item
+                   name="Tiles Autotag"
+                   href="../index.html"/>
+        </menu>
+
+        <menu ref="modules" />
+        <menu ref="reports" />
+
+    </body>
+</project>
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-freemarker/src/test/java/org/apache/tiles/autotag/freemarker/FMModelGeneratorTest.java b/Java-base/tiles-autotag/src/tiles-autotag-freemarker/src/test/java/org/apache/tiles/autotag/freemarker/FMModelGeneratorTest.java
new file mode 100644
index 000000000..fbd3b0efe
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-freemarker/src/test/java/org/apache/tiles/autotag/freemarker/FMModelGeneratorTest.java
@@ -0,0 +1,144 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.freemarker;
+
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.tiles.autotag.core.DirectoryOutputLocator;
+import org.apache.tiles.autotag.core.OutputLocator;
+import org.apache.tiles.autotag.core.runtime.ModelBody;
+import org.apache.tiles.autotag.model.TemplateClass;
+import org.apache.tiles.autotag.model.TemplateMethod;
+import org.apache.tiles.autotag.model.TemplateParameter;
+import org.apache.tiles.autotag.model.TemplateSuite;
+import org.apache.velocity.app.VelocityEngine;
+import org.junit.Test;
+
+/**
+ * Tests {@link TagClassGenerator}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class FMModelGeneratorTest {
+
+    public static final String REQUEST_CLASS = "org.apache.tiles.autotag.freemarker.test.Request";
+
+    /**
+     * Test method for {@link TagClassGenerator#generate(File, String, TemplateSuite, TemplateClass, java.util.Map)}.
+     * @throws Exception If something goes wrong.
+     */
+    @Test
+    public void testGenerate() throws Exception {
+        Properties props = new Properties();
+        InputStream propsStream = getClass().getResourceAsStream("/org/apache/tiles/autotag/velocity.properties");
+        props.load(propsStream);
+        propsStream.close();
+        VelocityEngine velocityEngine = new VelocityEngine(props);
+
+        FMModelGenerator generator = new FMModelGenerator(velocityEngine);
+        File tempDir = new File(System.getProperty("java.io.tmpdir"), "autotag");
+        OutputLocator locator = new DirectoryOutputLocator(tempDir);
+        tempDir.deleteOnExit();
+        TemplateSuite suite = new TemplateSuite("tldtest", "Test for TLD docs.");
+
+        List<TemplateParameter> params = new ArrayList<TemplateParameter>();
+        TemplateParameter param = new TemplateParameter("one", "one", "java.lang.String", null, true, false);
+        param.setDocumentation("Parameter one.");
+        params.add(param);
+        param = new TemplateParameter("two", "two", "int", null, false, false);
+        param.setDocumentation("Parameter two.");
+        params.add(param);
+        param = new TemplateParameter("three", "three", "boolean", null, false, false);
+        param.setDocumentation("Parameter three.");
+        params.add(param);
+        param = new TemplateParameter("request", "request", REQUEST_CLASS, null, false, true);
+        param.setDocumentation("The request.");
+        params.add(param);
+        param = new TemplateParameter("modelBody", "modelBody", ModelBody.class.getName(), null, false, false);
+        param.setDocumentation("The body.");
+        params.add(param);
+        TemplateMethod executeMethod = new TemplateMethod("execute", params);
+
+        TemplateClass clazz = new TemplateClass("org.apache.tiles.autotag.template.DoStuffTemplate",
+                "doStuff", "DoStuff", executeMethod);
+        clazz.setDocumentation("Documentation of the DoStuff class.");
+
+        generator.generate(locator, "org.apache.tiles.autotag.freemarker.test", suite, clazz, null,
+                           "org.apache.tiles.autotag.freemarker.test.Runtime", REQUEST_CLASS);
+
+        InputStream expected = getClass()
+                .getResourceAsStream(
+                        "/org/apache/tiles/autotag/freemarker/test/DoStuffFMModel.javat");
+        File effectiveFile = new File(tempDir, "/org/apache/tiles/autotag/freemarker/test/DoStuffFMModel.java");
+        assertTrue(effectiveFile.exists());
+        InputStream effective = new FileInputStream(effectiveFile);
+        assertTrue(IOUtils.contentEquals(effective, expected));
+        effective.close();
+        expected.close();
+
+        suite.addTemplateClass(clazz);
+        params = new ArrayList<TemplateParameter>();
+        param = new TemplateParameter("one", "one", "java.lang.Double", null, true, false);
+        param.setDocumentation("Parameter one.");
+        params.add(param);
+        param = new TemplateParameter("two", "two", "float", null, false, false);
+        param.setDocumentation("Parameter two.");
+        params.add(param);
+        param = new TemplateParameter("three", "three", "java.util.Date", null, false, false);
+        param.setDocumentation("Parameter three.");
+        params.add(param);
+        param = new TemplateParameter("request", "request", REQUEST_CLASS, null, false, true);
+        param.setDocumentation("The request.");
+        params.add(param);
+        executeMethod = new TemplateMethod("execute", params);
+
+        clazz = new TemplateClass("org.apache.tiles.autotag.template.DoStuffNoBodyTemplate",
+                "doStuffNoBody", "DoStuffNoBody", executeMethod);
+        clazz.setDocumentation("Documentation of the DoStuffNoBody class.");
+
+        suite.addTemplateClass(clazz);
+
+        generator.generate(locator, "org.apache.tiles.autotag.freemarker.test", suite, clazz, null,
+                           "org.apache.tiles.autotag.freemarker.test.Runtime", REQUEST_CLASS);
+
+        expected = getClass()
+                .getResourceAsStream(
+                        "/org/apache/tiles/autotag/freemarker/test/DoStuffNoBodyFMModel.javat");
+        effectiveFile = new File(tempDir, "/org/apache/tiles/autotag/freemarker/test/DoStuffNoBodyFMModel.java");
+        assertTrue(effectiveFile.exists());
+        effective = new FileInputStream(effectiveFile);
+        assertTrue(IOUtils.contentEquals(effective, expected));
+        effective.close();
+        expected.close();
+
+        FileUtils.deleteDirectory(tempDir);
+    }
+
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-freemarker/src/test/java/org/apache/tiles/autotag/freemarker/FMModelRepositoryGeneratorTest.java b/Java-base/tiles-autotag/src/tiles-autotag-freemarker/src/test/java/org/apache/tiles/autotag/freemarker/FMModelRepositoryGeneratorTest.java
new file mode 100644
index 000000000..bb8d02231
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-freemarker/src/test/java/org/apache/tiles/autotag/freemarker/FMModelRepositoryGeneratorTest.java
@@ -0,0 +1,130 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.freemarker;
+
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.tiles.autotag.core.DirectoryOutputLocator;
+import org.apache.tiles.autotag.core.OutputLocator;
+import org.apache.tiles.autotag.core.runtime.ModelBody;
+import org.apache.tiles.autotag.model.TemplateClass;
+import org.apache.tiles.autotag.model.TemplateMethod;
+import org.apache.tiles.autotag.model.TemplateParameter;
+import org.apache.tiles.autotag.model.TemplateSuite;
+import org.apache.velocity.app.VelocityEngine;
+import org.junit.Test;
+
+/**
+ * Tests {@link TLDGenerator}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class FMModelRepositoryGeneratorTest {
+
+    public static final String REQUEST_CLASS = "org.apache.tiles.autotag.freemarker.test.Request";
+
+    /**
+     * Test method for {@link FMModelRepositoryGenerator#generate(File, String, TemplateSuite, java.util.Map)}.
+     * @throws Exception If something goes wrong.
+     */
+    @Test
+    public void testGenerate() throws Exception {
+        Properties props = new Properties();
+        InputStream propsStream = getClass().getResourceAsStream("/org/apache/tiles/autotag/velocity.properties");
+        props.load(propsStream);
+        propsStream.close();
+        VelocityEngine velocityEngine = new VelocityEngine(props);
+
+        FMModelRepositoryGenerator generator = new FMModelRepositoryGenerator(velocityEngine);
+        File tempDir = new File(System.getProperty("java.io.tmpdir"), "autotag");
+        OutputLocator locator = new DirectoryOutputLocator(tempDir);
+        tempDir.deleteOnExit();
+        TemplateSuite suite = new TemplateSuite("tldtest", "Test for TLD docs.");
+
+        List<TemplateParameter> params = new ArrayList<TemplateParameter>();
+        TemplateParameter param = new TemplateParameter("one", "one", "java.lang.String", null, true, false);
+        param.setDocumentation("Parameter one.");
+        params.add(param);
+        param = new TemplateParameter("two", "two", "int", null, false, false);
+        param.setDocumentation("Parameter two.");
+        params.add(param);
+        param = new TemplateParameter("three", "three", "long", null, false, false);
+        param.setDocumentation("Parameter three.");
+        params.add(param);
+        param = new TemplateParameter("request", "request", REQUEST_CLASS, null, false, true);
+        param.setDocumentation("The request.");
+        params.add(param);
+        param = new TemplateParameter("modelBody", "modelBody", ModelBody.class.getName(), null, false, false);
+        param.setDocumentation("The body.");
+        params.add(param);
+        TemplateMethod executeMethod = new TemplateMethod("execute", params);
+
+        TemplateClass clazz = new TemplateClass("org.apache.tiles.autotag.template.DoStuffTemplate",
+                "doStuff", "DoStuff", executeMethod);
+        clazz.setDocumentation("Documentation of the DoStuff class");
+
+        suite.addTemplateClass(clazz);
+        params = new ArrayList<TemplateParameter>();
+        param = new TemplateParameter("one", "one", "java.lang.Double", null, true, false);
+        param.setDocumentation("Parameter one.");
+        params.add(param);
+        param = new TemplateParameter("two", "two", "float", null, false, false);
+        param.setDocumentation("Parameter two.");
+        params.add(param);
+        param = new TemplateParameter("three", "three", "java.util.Date", null, false, false);
+        param.setDocumentation("Parameter three.");
+        params.add(param);
+        param = new TemplateParameter("request", "request", REQUEST_CLASS, null, false, true);
+        param.setDocumentation("The request.");
+        params.add(param);
+        executeMethod = new TemplateMethod("execute", params);
+
+        clazz = new TemplateClass("org.apache.tiles.autotag.template.DoStuffNoBodyTemplate",
+                "doStuffNoBody", "DoStuffNoBody", executeMethod);
+        clazz.setDocumentation("Documentation of the DoStuffNoBody class");
+
+        suite.addTemplateClass(clazz);
+
+        generator.generate(locator, "org.apache.tiles.autotag.freemarker.test", suite, null);
+
+        InputStream expected = getClass()
+                .getResourceAsStream(
+                        "/org/apache/tiles/autotag/freemarker/test/TldtestFMModelRepository.javat");
+        File effectiveFile = new File(tempDir, "/org/apache/tiles/autotag/freemarker/test/TldtestFMModelRepository.java");
+        assertTrue(effectiveFile.exists());
+        InputStream effective = new FileInputStream(effectiveFile);
+        assertTrue(IOUtils.contentEquals(effective, expected));
+        effective.close();
+        expected.close();
+
+        FileUtils.deleteDirectory(tempDir);
+    }
+
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-freemarker/src/test/java/org/apache/tiles/autotag/freemarker/FMTemplateGeneratorFactoryTest.java b/Java-base/tiles-autotag/src/tiles-autotag-freemarker/src/test/java/org/apache/tiles/autotag/freemarker/FMTemplateGeneratorFactoryTest.java
new file mode 100644
index 000000000..373a14711
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-freemarker/src/test/java/org/apache/tiles/autotag/freemarker/FMTemplateGeneratorFactoryTest.java
@@ -0,0 +1,65 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.freemarker;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.isA;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.junit.Assert.assertSame;
+
+import org.apache.tiles.autotag.core.OutputLocator;
+import org.apache.tiles.autotag.generate.TemplateGenerator;
+import org.apache.tiles.autotag.generate.TemplateGeneratorBuilder;
+import org.apache.velocity.app.VelocityEngine;
+import org.junit.Test;
+
+/**
+ * Tests {@link FMTemplateGeneratorFactory}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class FMTemplateGeneratorFactoryTest {
+
+    /**
+     * Test method for {@link org.apache.tiles.autotag.freemarker.FMTemplateGeneratorFactory#createTemplateGenerator()}.
+     */
+    @Test
+    public void testCreateTemplateGenerator() {
+        OutputLocator classesOutputLocator = createMock(OutputLocator.class);
+        VelocityEngine velocityEngine = createMock(VelocityEngine.class);
+        TemplateGeneratorBuilder builder = createMock(TemplateGeneratorBuilder.class);
+        TemplateGenerator generator = createMock(TemplateGenerator.class);
+
+        expect(builder.setClassesOutputLocator(classesOutputLocator)).andReturn(builder);
+        expect(builder.addClassesTemplateSuiteGenerator(isA(FMModelRepositoryGenerator.class))).andReturn(builder);
+        expect(builder.addClassesTemplateClassGenerator(isA(FMModelGenerator.class))).andReturn(builder);
+        expect(builder.build()).andReturn(generator);
+
+        replay(classesOutputLocator, velocityEngine, builder, generator);
+        FMTemplateGeneratorFactory factory = new FMTemplateGeneratorFactory(
+        		classesOutputLocator, velocityEngine, builder);
+        assertSame(generator, factory.createTemplateGenerator());
+        verify(classesOutputLocator, velocityEngine, builder, generator);
+    }
+
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-freemarker/src/test/resources/org/apache/tiles/autotag/freemarker/test/DoStuffFMModel.javat b/Java-base/tiles-autotag/src/tiles-autotag-freemarker/src/test/resources/org/apache/tiles/autotag/freemarker/test/DoStuffFMModel.javat
new file mode 100644
index 000000000..8d54c8cfe
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-freemarker/src/test/resources/org/apache/tiles/autotag/freemarker/test/DoStuffFMModel.javat
@@ -0,0 +1,56 @@
+/*
+ * This file was automatically generated by Apache Tiles Autotag.
+ */
+package org.apache.tiles.autotag.freemarker.test;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.apache.tiles.autotag.core.runtime.ModelBody;
+import org.apache.tiles.autotag.core.runtime.AutotagRuntime;
+
+import freemarker.core.Environment;
+import freemarker.template.TemplateDirectiveBody;
+import freemarker.template.TemplateDirectiveModel;
+import freemarker.template.TemplateException;
+import freemarker.template.TemplateModel;
+
+/**
+ * Documentation of the DoStuff class.
+ */
+public class DoStuffFMModel implements TemplateDirectiveModel {
+
+    /**
+     * The template model.
+     */
+    private org.apache.tiles.autotag.template.DoStuffTemplate model;
+
+    /**
+     * Constructor.
+     *
+     * @param model
+     *            The template model.
+     */
+    public DoStuffFMModel(org.apache.tiles.autotag.template.DoStuffTemplate model) {
+        this.model = model;
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
+    @Override
+    public void execute(Environment env, @SuppressWarnings("rawtypes") Map params, TemplateModel[] loopVars,
+            TemplateDirectiveBody body) throws TemplateException, IOException {
+        AutotagRuntime<org.apache.tiles.autotag.freemarker.test.Request> runtime = new org.apache.tiles.autotag.freemarker.test.Runtime();
+        if (runtime instanceof TemplateDirectiveModel) {
+            ((TemplateDirectiveModel) runtime).execute(env, params, loopVars, body);
+        }
+        org.apache.tiles.autotag.freemarker.test.Request request = runtime.createRequest();
+        ModelBody modelBody = runtime.createModelBody();
+        model.execute(
+            runtime.getParameter("one", java.lang.String.class, null),
+            runtime.getParameter("two", java.lang.Integer.class, 0),
+            runtime.getParameter("three", java.lang.Boolean.class, false),
+                request, modelBody
+        );
+    }
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-freemarker/src/test/resources/org/apache/tiles/autotag/freemarker/test/DoStuffNoBodyFMModel.javat b/Java-base/tiles-autotag/src/tiles-autotag-freemarker/src/test/resources/org/apache/tiles/autotag/freemarker/test/DoStuffNoBodyFMModel.javat
new file mode 100644
index 000000000..ef0ac5101
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-freemarker/src/test/resources/org/apache/tiles/autotag/freemarker/test/DoStuffNoBodyFMModel.javat
@@ -0,0 +1,54 @@
+/*
+ * This file was automatically generated by Apache Tiles Autotag.
+ */
+package org.apache.tiles.autotag.freemarker.test;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.apache.tiles.autotag.core.runtime.AutotagRuntime;
+
+import freemarker.core.Environment;
+import freemarker.template.TemplateDirectiveBody;
+import freemarker.template.TemplateDirectiveModel;
+import freemarker.template.TemplateException;
+import freemarker.template.TemplateModel;
+
+/**
+ * Documentation of the DoStuffNoBody class.
+ */
+public class DoStuffNoBodyFMModel implements TemplateDirectiveModel {
+
+    /**
+     * The template model.
+     */
+    private org.apache.tiles.autotag.template.DoStuffNoBodyTemplate model;
+
+    /**
+     * Constructor.
+     *
+     * @param model
+     *            The template model.
+     */
+    public DoStuffNoBodyFMModel(org.apache.tiles.autotag.template.DoStuffNoBodyTemplate model) {
+        this.model = model;
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
+    @Override
+    public void execute(Environment env, @SuppressWarnings("rawtypes") Map params, TemplateModel[] loopVars,
+            TemplateDirectiveBody body) throws TemplateException, IOException {
+        AutotagRuntime<org.apache.tiles.autotag.freemarker.test.Request> runtime = new org.apache.tiles.autotag.freemarker.test.Runtime();
+        if (runtime instanceof TemplateDirectiveModel) {
+            ((TemplateDirectiveModel) runtime).execute(env, params, loopVars, body);
+        }
+        org.apache.tiles.autotag.freemarker.test.Request request = runtime.createRequest();
+        model.execute(
+            runtime.getParameter("one", java.lang.Double.class, null),
+            runtime.getParameter("two", java.lang.Float.class, 0.0f),
+            runtime.getParameter("three", java.util.Date.class, null),
+                request
+        );
+    }
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-freemarker/src/test/resources/org/apache/tiles/autotag/freemarker/test/TldtestFMModelRepository.javat b/Java-base/tiles-autotag/src/tiles-autotag-freemarker/src/test/resources/org/apache/tiles/autotag/freemarker/test/TldtestFMModelRepository.javat
new file mode 100644
index 000000000..4fe08ee36
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-freemarker/src/test/resources/org/apache/tiles/autotag/freemarker/test/TldtestFMModelRepository.javat
@@ -0,0 +1,46 @@
+/*
+ * This file was automatically generated by Apache Tiles Autotag.
+ */
+package org.apache.tiles.autotag.freemarker.test;
+
+/**
+ * Test for TLD docs.
+ */
+public class TldtestFMModelRepository {
+
+    /**
+     * The "doStuff" directive.
+     */
+    private DoStuffFMModel doStuff;
+
+    /**
+     * The "doStuffNoBody" directive.
+     */
+    private DoStuffNoBodyFMModel doStuffNoBody;
+
+    /**
+     * Constructor.
+     */
+    public TilesFMModelRepository() {
+        doStuff = new DoStuffFMModel(new org.apache.tiles.autotag.template.DoStuffTemplate());
+        doStuffNoBody = new DoStuffNoBodyFMModel(new org.apache.tiles.autotag.template.DoStuffNoBodyTemplate());
+    }
+
+    /**
+     * Returns the "doStuff" directive.
+     *
+     * @return The "doStuff" directive.
+     */
+    public DoStuffFMModel getDoStuff() {
+        return doStuff;
+    }
+
+    /**
+     * Returns the "doStuffNoBody" directive.
+     *
+     * @return The "doStuffNoBody" directive.
+     */
+    public DoStuffNoBodyFMModel getDoStuffNoBody() {
+        return doStuffNoBody;
+    }
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-jsp/pom.xml b/Java-base/tiles-autotag/src/tiles-autotag-jsp/pom.xml
new file mode 100644
index 000000000..0f0ba5a58
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-jsp/pom.xml
@@ -0,0 +1,59 @@
+<?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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <artifactId>tiles-autotag</artifactId>
+    <groupId>org.apache.tiles</groupId>
+    <version>1.3-SNAPSHOT</version>
+  </parent>
+  <groupId>org.apache.tiles</groupId>
+  <artifactId>tiles-autotag-jsp</artifactId>
+  <version>1.3-SNAPSHOT</version>
+  <name>Tiles Autotag - JSP tags automatic generation</name>
+  <description>Generates JSP tags automatically from templates.</description>
+  <properties>
+        <!-- decrease this whenever possible -->
+        <checkstyle.maxAllowedViolations>1</checkstyle.maxAllowedViolations>
+  </properties>
+  <dependencies>
+    <dependency>
+        <groupId>junit</groupId>
+        <artifactId>junit</artifactId>
+        <scope>test</scope>
+    </dependency>
+    <dependency>
+        <groupId>commons-io</groupId>
+        <artifactId>commons-io</artifactId>
+        <scope>test</scope>
+    </dependency>
+    <dependency>
+    	<groupId>org.apache.tiles</groupId>
+    	<artifactId>tiles-autotag-core</artifactId>
+    </dependency>
+    <dependency>
+    	<groupId>org.easymock</groupId>
+    	<artifactId>easymock</artifactId>
+    	<scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-jsp/src/main/java/org/apache/tiles/autotag/jsp/JspTemplateGeneratorFactory.java b/Java-base/tiles-autotag/src/tiles-autotag-jsp/src/main/java/org/apache/tiles/autotag/jsp/JspTemplateGeneratorFactory.java
new file mode 100644
index 000000000..1f9592aed
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-jsp/src/main/java/org/apache/tiles/autotag/jsp/JspTemplateGeneratorFactory.java
@@ -0,0 +1,84 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.jsp;
+
+import org.apache.tiles.autotag.core.OutputLocator;
+import org.apache.tiles.autotag.generate.TemplateGenerator;
+import org.apache.tiles.autotag.generate.TemplateGeneratorBuilder;
+import org.apache.tiles.autotag.generate.TemplateGeneratorFactory;
+import org.apache.velocity.app.VelocityEngine;
+
+/**
+ * Creates a template generator to build JSP code around template models.
+ *
+ * @version $Rev$ $Date$
+ */
+public class JspTemplateGeneratorFactory implements TemplateGeneratorFactory {
+
+    /**
+     * Location of the file.
+     */
+    private OutputLocator classesOutputLocator;
+
+    /**
+     * Location of the file.
+     */
+    private OutputLocator resourcesOutputLocator;
+
+    /**
+     * The Velocity engine.
+     */
+    private VelocityEngine velocityEngine;
+
+    /**
+     * The template generator builder.
+     */
+    private TemplateGeneratorBuilder templateGeneratorBuilder;
+
+    /**
+     * Constructor.
+     *
+     * @param classesOutputLocator The directory where classes will be generated.
+     * @param resourcesOutputLocator The directory where the TLD file will be generated.
+     * @param velocityEngine The Velocity engine.
+     * @param templateGeneratorBuilder The template generator builder.
+     */
+    public JspTemplateGeneratorFactory(OutputLocator classesOutputLocator,
+    		OutputLocator resourcesOutputLocator, VelocityEngine velocityEngine,
+            TemplateGeneratorBuilder templateGeneratorBuilder) {
+        this.classesOutputLocator = classesOutputLocator;
+        this.resourcesOutputLocator = resourcesOutputLocator;
+        this.velocityEngine = velocityEngine;
+        this.templateGeneratorBuilder = templateGeneratorBuilder;
+    }
+
+    @Override
+    public TemplateGenerator createTemplateGenerator() {
+        return templateGeneratorBuilder
+                .setClassesOutputLocator(classesOutputLocator)
+                .setResourcesOutputLocator(resourcesOutputLocator)
+                .addResourcesTemplateSuiteGenerator(
+                        new TLDGenerator(velocityEngine))
+                .addClassesTemplateClassGenerator(
+                        new TagClassGenerator(velocityEngine)).build();
+    }
+
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-jsp/src/main/java/org/apache/tiles/autotag/jsp/TLDGenerator.java b/Java-base/tiles-autotag/src/tiles-autotag-jsp/src/main/java/org/apache/tiles/autotag/jsp/TLDGenerator.java
new file mode 100644
index 000000000..3e12a7bd5
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-jsp/src/main/java/org/apache/tiles/autotag/jsp/TLDGenerator.java
@@ -0,0 +1,63 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.jsp;
+
+import java.util.Map;
+
+import org.apache.tiles.autotag.generate.AbstractTemplateSuiteGenerator;
+import org.apache.tiles.autotag.model.TemplateSuite;
+import org.apache.velocity.app.VelocityEngine;
+
+/**
+ * Generates the TLD file, using a template suite.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TLDGenerator extends AbstractTemplateSuiteGenerator {
+
+    /**
+     * Constructor.
+     *
+     * @param velocityEngine The Velocity engine.
+     */
+    public TLDGenerator(VelocityEngine velocityEngine) {
+        super(velocityEngine);
+    }
+
+    @Override
+    protected String getTemplatePath(String packageName,
+            TemplateSuite suite, Map<String, String> parameters) {
+        return "/org/apache/tiles/autotag/jsp/tld.vm";
+    }
+
+    @Override
+    protected String getFilename(String packageName,
+            TemplateSuite suite, Map<String, String> parameters) {
+        return suite.getName() + "-jsp.tld";
+    }
+
+    @Override
+    protected String getDirectoryName(String packageName,
+            TemplateSuite suite, Map<String, String> parameters) {
+        return "META-INF/tld/";
+    }
+
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-jsp/src/main/java/org/apache/tiles/autotag/jsp/TagClassGenerator.java b/Java-base/tiles-autotag/src/tiles-autotag-jsp/src/main/java/org/apache/tiles/autotag/jsp/TagClassGenerator.java
new file mode 100644
index 000000000..0f3d6b6b3
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-jsp/src/main/java/org/apache/tiles/autotag/jsp/TagClassGenerator.java
@@ -0,0 +1,66 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.jsp;
+
+import java.util.Map;
+
+import org.apache.tiles.autotag.generate.AbstractTemplateClassGenerator;
+import org.apache.tiles.autotag.model.TemplateClass;
+import org.apache.tiles.autotag.model.TemplateSuite;
+import org.apache.velocity.app.VelocityEngine;
+
+/**
+ * Generates a tag class using a template class.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TagClassGenerator extends AbstractTemplateClassGenerator {
+
+    /**
+     * Constructor.
+     *
+     * @param velocityEngine The Velocity engine.
+     */
+    public TagClassGenerator(VelocityEngine velocityEngine) {
+        super(velocityEngine);
+    }
+
+    @Override
+    protected String getDirectoryName(String packageName,
+            TemplateSuite suite, TemplateClass clazz, Map<String, String> parameters,
+            String runtimeClass, String requestClass) {
+        return packageName.replaceAll("\\.", "/");
+    }
+
+    @Override
+    protected String getFilename(String packageName,
+            TemplateSuite suite, TemplateClass clazz, Map<String, String> parameters,
+            String runtimeClass, String requestClass) {
+        return clazz.getTagClassPrefix() + "Tag.java";
+    }
+
+    @Override
+    protected String getTemplatePath(String packageName,
+            TemplateSuite suite, TemplateClass clazz, Map<String, String> parameters,
+            String runtimeClass, String requestClass) {
+        return "/org/apache/tiles/autotag/jsp/bodyTag.vm";
+    }
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-jsp/src/main/java/org/apache/tiles/autotag/jsp/package-info.java b/Java-base/tiles-autotag/src/tiles-autotag-jsp/src/main/java/org/apache/tiles/autotag/jsp/package-info.java
new file mode 100644
index 000000000..e75b5c0fd
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-jsp/src/main/java/org/apache/tiles/autotag/jsp/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * Autotag support for JavaServer Pages.
+ */
+package org.apache.tiles.autotag.jsp;
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-jsp/src/main/resources/org/apache/tiles/autotag/jsp/bodyTag.vm b/Java-base/tiles-autotag/src/tiles-autotag-jsp/src/main/resources/org/apache/tiles/autotag/jsp/bodyTag.vm
new file mode 100644
index 000000000..f686fe761
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-jsp/src/main/resources/org/apache/tiles/autotag/jsp/bodyTag.vm
@@ -0,0 +1,105 @@
+#*
+ * $Id: tiles-jsp.tld 836180 2009-11-14 14:00:02Z apetrelli $
+ *
+ * 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.
+ *#/*
+ * This file was automatically generated by Apache Tiles Autotag.
+ */
+package ${packageName};
+
+import java.io.IOException;
+
+import javax.servlet.jsp.JspException;
+import javax.servlet.jsp.tagext.SimpleTagSupport;
+
+#if(${clazz.hasBody()})
+import org.apache.tiles.autotag.core.runtime.ModelBody;
+#end
+import org.apache.tiles.autotag.core.runtime.AutotagRuntime;
+
+/**
+#foreach($line in $stringTool.splitOnNewlines(${clazz.documentation}))
+ * ${line}
+#end
+ */
+public class ${clazz.tagClassPrefix}Tag extends SimpleTagSupport {
+
+    /**
+     * The template model.
+     */
+    private ${clazz.name} model = new ${clazz.name}();
+
+#foreach($parameter in ${clazz.parameters})
+    /**
+#foreach($line in $stringTool.splitOnNewlines(${parameter.documentation}))
+     * ${line}
+#end
+     */
+    private ${parameter.type} ${parameter.name};
+
+#end
+#foreach($parameter in ${clazz.parameters})
+    /**
+     * Getter for ${parameter.exportedName} property.
+     *
+     * @return
+#foreach($line in $stringTool.splitOnNewlines(${parameter.documentation}))
+     * ${line}
+#end
+     */
+    public ${parameter.type} #if(${parameter.type} == 'boolean')is#{else}get#end${parameter.getterSetterSuffix}() {
+        return ${parameter.name};
+    }
+
+    /**
+     * Setter for ${parameter.exportedName} property.
+     *
+     * @param ${parameter.name}
+#foreach($line in $stringTool.splitOnNewlines(${parameter.documentation}))
+     * ${line}
+#end
+     */
+    public void set${parameter.getterSetterSuffix}(${parameter.type} ${parameter.name}) {
+        this.${parameter.name} = ${parameter.name};
+    }
+
+#end
+    /** {@inheritDoc} */
+    @Override
+    public void doTag() throws JspException, IOException {
+        AutotagRuntime<${requestClass}> runtime = new ${runtimeClass}();
+        if (runtime instanceof SimpleTagSupport) {
+            SimpleTagSupport tag = (SimpleTagSupport) runtime;
+            tag.setJspContext(getJspContext());
+            tag.setJspBody(getJspBody());
+            tag.setParent(getParent());
+            tag.doTag();
+        }
+        ${requestClass} request = runtime.createRequest();        
+#if(${clazz.hasBody()})
+        ModelBody modelBody = runtime.createModelBody();
+#end
+        model.execute(
+#foreach($parameter in ${clazz.parameters})
+            ${parameter.name},
+#end
+            request#if(${clazz.hasBody()}), modelBody#end
+
+        );
+    }
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-jsp/src/main/resources/org/apache/tiles/autotag/jsp/tld.vm b/Java-base/tiles-autotag/src/tiles-autotag-jsp/src/main/resources/org/apache/tiles/autotag/jsp/tld.vm
new file mode 100644
index 000000000..9d4c0e9be
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-jsp/src/main/resources/org/apache/tiles/autotag/jsp/tld.vm
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+#*
+ * $Id: tiles-jsp.tld 836180 2009-11-14 14:00:02Z apetrelli $
+ *
+ * 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.
+ *#
+<!-- This file was automatically generated by Apache Tiles Autotag. -->
+<taglib
+  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
+  xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  version="2.1">
+   <description>
+   <![CDATA[
+#foreach($line in $stringTool.splitOnNewlines(${suite.documentation}))
+   $line
+#end
+   ]]>
+   </description>
+   <tlib-version>1.2</tlib-version>
+   <short-name>${suite.name}</short-name>
+   <uri>${parameters.taglibURI}</uri>
+#foreach($clazz in ${suite.getTemplateClasses()})
+   <tag>
+      <description>
+      <![CDATA[
+#foreach($line in $stringTool.splitOnNewlines(${clazz.documentation}))
+      $line
+#end
+      ]]>
+      </description>
+      <name>${clazz.tagName}</name>
+      <tag-class>${packageName}.${clazz.tagClassPrefix}Tag</tag-class>
+      <body-content>#if(${clazz.hasBody()})scriptless#{else}empty#end</body-content>
+#foreach($parameter in ${clazz.parameters})
+      <attribute>
+         <description>
+         <![CDATA[
+#foreach($line in $stringTool.splitOnNewlines(${parameter.documentation}))
+         $line
+#end
+         ]]>
+         </description>
+         <name>${parameter.exportedName}</name>
+         <required>${parameter.required}</required>
+         <rtexprvalue>true</rtexprvalue>
+         <type>${parameter.type}</type>
+      </attribute>
+#end
+   </tag>
+#end
+</taglib>
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-jsp/src/site/site.xml b/Java-base/tiles-autotag/src/tiles-autotag-jsp/src/site/site.xml
new file mode 100644
index 000000000..0a7d00df4
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-jsp/src/site/site.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+/*
+ * $Id: site.xml 1081442 2011-03-14 16:21:08Z apetrelli $
+ *
+ * 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.
+ */
+-->
+<project name="Apache - Tiles Autotags">
+    <bannerLeft>
+        <name>Apache Software Foundation</name>
+        <src>http://www.apache.org/images/asf-logo.gif</src>
+        <href>http://www.apache.org</href>
+    </bannerLeft>
+    <bannerRight>
+        <name>Apache Tiles&#8482;</name>
+        <src>http://tiles.apache.org/images/logo.png</src>
+        <href>http://tiles.apache.org</href>
+    </bannerRight>
+    <body>
+
+        <links>
+            <item name="Apache" href="http://www.apache.org" />
+            <item name="Tiles" href="http://tiles.apache.org" />
+        </links>
+
+
+        <menu name="Apache Tiles&#8482;">
+            <item
+                   name="Tiles Home"
+                   href="../../index.html"/>
+            <item
+                   name="Tiles Autotag"
+                   href="../index.html"/>
+        </menu>
+
+        <menu ref="modules" />
+        <menu ref="reports" />
+
+    </body>
+</project>
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-jsp/src/test/java/org/apache/tiles/autotag/jsp/JspTemplateGeneratorFactoryTest.java b/Java-base/tiles-autotag/src/tiles-autotag-jsp/src/test/java/org/apache/tiles/autotag/jsp/JspTemplateGeneratorFactoryTest.java
new file mode 100644
index 000000000..9f7e534ca
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-jsp/src/test/java/org/apache/tiles/autotag/jsp/JspTemplateGeneratorFactoryTest.java
@@ -0,0 +1,68 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.jsp;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.isA;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.junit.Assert.assertSame;
+
+import org.apache.tiles.autotag.core.OutputLocator;
+import org.apache.tiles.autotag.generate.TemplateGenerator;
+import org.apache.tiles.autotag.generate.TemplateGeneratorBuilder;
+import org.apache.velocity.app.VelocityEngine;
+import org.junit.Test;
+
+/**
+ * Tests {@link JspTemplateGeneratorFactory}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class JspTemplateGeneratorFactoryTest {
+
+    /**
+     * Test method for {@link JspTemplateGeneratorFactory#createTemplateGenerator()}.
+     */
+    @Test
+    public void testCreateTemplateGenerator() {
+    	OutputLocator classesOutputLocator = createMock(OutputLocator.class);
+    	OutputLocator resourcesOutputLocator = createMock(OutputLocator.class);
+        VelocityEngine velocityEngine = createMock(VelocityEngine.class);
+        TemplateGeneratorBuilder builder = createMock(TemplateGeneratorBuilder.class);
+        TemplateGenerator generator = createMock(TemplateGenerator.class);
+
+        expect(builder.setClassesOutputLocator(classesOutputLocator)).andReturn(builder);
+        expect(builder.setResourcesOutputLocator(resourcesOutputLocator)).andReturn(builder);
+        expect(builder.addResourcesTemplateSuiteGenerator(isA(TLDGenerator.class))).andReturn(builder);
+        expect(builder.addClassesTemplateClassGenerator(isA(TagClassGenerator.class))).andReturn(builder);
+        expect(builder.build()).andReturn(generator);
+
+        replay(classesOutputLocator, resourcesOutputLocator, velocityEngine, builder, generator);
+        JspTemplateGeneratorFactory factory = new JspTemplateGeneratorFactory(
+                classesOutputLocator, resourcesOutputLocator,
+                velocityEngine, builder);
+        assertSame(generator, factory.createTemplateGenerator());
+        verify(classesOutputLocator, resourcesOutputLocator, velocityEngine, builder, generator);
+    }
+
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-jsp/src/test/java/org/apache/tiles/autotag/jsp/TLDGeneratorTest.java b/Java-base/tiles-autotag/src/tiles-autotag-jsp/src/test/java/org/apache/tiles/autotag/jsp/TLDGeneratorTest.java
new file mode 100644
index 000000000..daefbbad5
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-jsp/src/test/java/org/apache/tiles/autotag/jsp/TLDGeneratorTest.java
@@ -0,0 +1,132 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.jsp;
+
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.tiles.autotag.core.DirectoryOutputLocator;
+import org.apache.tiles.autotag.core.OutputLocator;
+import org.apache.tiles.autotag.core.runtime.ModelBody;
+import org.apache.tiles.autotag.model.TemplateClass;
+import org.apache.tiles.autotag.model.TemplateMethod;
+import org.apache.tiles.autotag.model.TemplateParameter;
+import org.apache.tiles.autotag.model.TemplateSuite;
+import org.apache.velocity.app.VelocityEngine;
+import org.junit.Test;
+
+/**
+ * Tests {@link TLDGenerator}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TLDGeneratorTest {
+
+    public static final String REQUEST_CLASS = "org.apache.tiles.autotag.jsp.test.Request";
+
+    /**
+     * Test method for {@link TLDGenerator#generate(File, String, TemplateSuite, Map)}.
+     * @throws Exception If something goes wrong.
+     */
+    @Test
+    public void testGenerate() throws Exception {
+        Properties props = new Properties();
+        InputStream propsStream = getClass().getResourceAsStream("/org/apache/tiles/autotag/velocity.properties");
+        props.load(propsStream);
+        propsStream.close();
+        VelocityEngine velocityEngine = new VelocityEngine(props);
+
+        TLDGenerator generator = new TLDGenerator(velocityEngine);
+        File tempDir = new File(System.getProperty("java.io.tmpdir"), "autotag");
+        OutputLocator locator = new DirectoryOutputLocator(tempDir);
+        tempDir.deleteOnExit();
+        TemplateSuite suite = new TemplateSuite("tldtest", "Test for TLD docs.");
+        Map<String, String> parameters = new HashMap<String, String>();
+        parameters.put("taglibURI", "http://www.initrode.net/tags/test");
+
+        List<TemplateParameter> params = new ArrayList<TemplateParameter>();
+        TemplateParameter param = new TemplateParameter("one", "one", "java.lang.String", null, true, false);
+        param.setDocumentation("Parameter one.");
+        params.add(param);
+        param = new TemplateParameter("two", "two", "int", null, false, false);
+        param.setDocumentation("Parameter two.");
+        params.add(param);
+        param = new TemplateParameter("three", "three", "long", null, false, false);
+        param.setDocumentation("Parameter three.");
+        params.add(param);
+        param = new TemplateParameter("request", "request", REQUEST_CLASS, null, false, true);
+        param.setDocumentation("The request.");
+        params.add(param);
+        param = new TemplateParameter("modelBody", "modelBody", ModelBody.class.getName(), null, false, false);
+        param.setDocumentation("The body.");
+        params.add(param);
+        TemplateMethod executeMethod = new TemplateMethod("execute", params);
+
+        TemplateClass clazz = new TemplateClass("org.apache.tiles.autotag.template.DoStuffTemplate",
+                "doStuff", "DoStuff", executeMethod);
+        clazz.setDocumentation("Documentation of the DoStuff class");
+
+        suite.addTemplateClass(clazz);
+        params = new ArrayList<TemplateParameter>();
+        param = new TemplateParameter("one", "one", "java.lang.Double", null, true, false);
+        param.setDocumentation("Parameter one.");
+        params.add(param);
+        param = new TemplateParameter("two", "two", "float", null, false, false);
+        param.setDocumentation("Parameter two.");
+        params.add(param);
+        param = new TemplateParameter("three", "three", "java.util.Date", null, false, false);
+        param.setDocumentation("Parameter three.");
+        params.add(param);
+        param = new TemplateParameter("request", "request", REQUEST_CLASS, null, false ,true);
+        param.setDocumentation("The request.");
+        params.add(param);
+        executeMethod = new TemplateMethod("execute", params);
+
+        clazz = new TemplateClass("org.apache.tiles.autotag.template.DoStuffNoBodyTemplate",
+                "doStuffNoBody", "DoStuffNoBody", executeMethod);
+        clazz.setDocumentation("Documentation of the DoStuffNoBody class");
+
+        suite.addTemplateClass(clazz);
+
+        generator.generate(locator, "org.apache.tiles.autotag.jsp.test", suite, parameters);
+
+        InputStream expected = getClass().getResourceAsStream("/tldtest-jsp.tld");
+        File effectiveFile = new File(tempDir, "META-INF/tld/tldtest-jsp.tld");
+        assertTrue(effectiveFile.exists());
+        InputStream effective = new FileInputStream(effectiveFile);
+        assertTrue(IOUtils.contentEquals(effective, expected));
+        effective.close();
+        expected.close();
+
+        FileUtils.deleteDirectory(tempDir);
+    }
+
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-jsp/src/test/java/org/apache/tiles/autotag/jsp/TagClassGeneratorTest.java b/Java-base/tiles-autotag/src/tiles-autotag-jsp/src/test/java/org/apache/tiles/autotag/jsp/TagClassGeneratorTest.java
new file mode 100644
index 000000000..4a8336639
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-jsp/src/test/java/org/apache/tiles/autotag/jsp/TagClassGeneratorTest.java
@@ -0,0 +1,144 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.jsp;
+
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.tiles.autotag.core.DirectoryOutputLocator;
+import org.apache.tiles.autotag.core.OutputLocator;
+import org.apache.tiles.autotag.core.runtime.ModelBody;
+import org.apache.tiles.autotag.model.TemplateClass;
+import org.apache.tiles.autotag.model.TemplateMethod;
+import org.apache.tiles.autotag.model.TemplateParameter;
+import org.apache.tiles.autotag.model.TemplateSuite;
+import org.apache.velocity.app.VelocityEngine;
+import org.junit.Test;
+
+/**
+ * Tests {@link TagClassGenerator}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TagClassGeneratorTest {
+
+    public static final String REQUEST_CLASS = "org.apache.tiles.autotag.jsp.test.Request";
+
+    /**
+     * Test method for {@link TagClassGenerator#generate(File, String, TemplateSuite, TemplateClass, Map)}.
+     * @throws Exception If something goes wrong.
+     */
+    @Test
+    public void testGenerate() throws Exception {
+        Properties props = new Properties();
+        InputStream propsStream = getClass().getResourceAsStream("/org/apache/tiles/autotag/velocity.properties");
+        props.load(propsStream);
+        propsStream.close();
+        VelocityEngine velocityEngine = new VelocityEngine(props);
+
+        TagClassGenerator generator = new TagClassGenerator(velocityEngine);
+        File tempDir = new File(System.getProperty("java.io.tmpdir"), "autotag");
+        OutputLocator locator = new DirectoryOutputLocator(tempDir);
+        tempDir.deleteOnExit();
+        TemplateSuite suite = new TemplateSuite("tldtest", "Test for TLD docs.");
+        Map<String, String> parameters = new HashMap<String, String>();
+        parameters.put("taglibURI", "http://www.initrode.net/tags/test");
+
+        List<TemplateParameter> params = new ArrayList<TemplateParameter>();
+        TemplateParameter param = new TemplateParameter("one", "one", "java.lang.String", null, true, false);
+        param.setDocumentation("Parameter one.");
+        params.add(param);
+        param = new TemplateParameter("two", "two", "int", null, false, false);
+        param.setDocumentation("Parameter two.");
+        params.add(param);
+        param = new TemplateParameter("three", "three", "boolean", null, false, false);
+        param.setDocumentation("Parameter three.");
+        params.add(param);
+        param = new TemplateParameter("request", "request", REQUEST_CLASS, null, false, true);
+        param.setDocumentation("The request.");
+        params.add(param);
+        param = new TemplateParameter("modelBody", "modelBody", ModelBody.class.getName(), null, false, false);
+        param.setDocumentation("The body.");
+        params.add(param);
+        TemplateMethod executeMethod = new TemplateMethod("execute", params);
+
+        TemplateClass clazz = new TemplateClass("org.apache.tiles.autotag.template.DoStuffTemplate",
+                "doStuff", "DoStuff", executeMethod);
+        clazz.setDocumentation("Documentation of the DoStuff class.");
+
+        generator.generate(locator, "org.apache.tiles.autotag.jsp.test", suite, clazz, parameters,
+                           "org.apache.tiles.autotag.jsp.test.Runtime", REQUEST_CLASS);
+
+        InputStream expected = getClass().getResourceAsStream("/org/apache/tiles/autotag/jsp/test/DoStuffTag.java");
+        File effectiveFile = new File(tempDir, "/org/apache/tiles/autotag/jsp/test/DoStuffTag.java");
+        assertTrue(effectiveFile.exists());
+        InputStream effective = new FileInputStream(effectiveFile);
+        assertTrue(IOUtils.contentEquals(effective, expected));
+        effective.close();
+        expected.close();
+
+        suite.addTemplateClass(clazz);
+        params = new ArrayList<TemplateParameter>();
+        param = new TemplateParameter("one", "one", "java.lang.Double", null, true, false);
+        param.setDocumentation("Parameter one.");
+        params.add(param);
+        param = new TemplateParameter("two", "two", "float", null, false, false);
+        param.setDocumentation("Parameter two.");
+        params.add(param);
+        param = new TemplateParameter("three", "three", "java.util.Date", null, false, false);
+        param.setDocumentation("Parameter three.");
+        params.add(param);
+        param = new TemplateParameter("request", "request", REQUEST_CLASS, null, false, true);
+        param.setDocumentation("The request.");
+        params.add(param);
+        executeMethod = new TemplateMethod("execute", params);
+
+        clazz = new TemplateClass("org.apache.tiles.autotag.template.DoStuffNoBodyTemplate",
+                "doStuffNoBody", "DoStuffNoBody", executeMethod);
+        clazz.setDocumentation("Documentation of the DoStuffNoBody class.");
+
+        suite.addTemplateClass(clazz);
+
+        generator.generate(locator, "org.apache.tiles.autotag.jsp.test", suite, clazz, parameters,
+                           "org.apache.tiles.autotag.jsp.test.Runtime", REQUEST_CLASS);
+
+        expected = getClass().getResourceAsStream("/org/apache/tiles/autotag/jsp/test/DoStuffNoBodyTag.java");
+        effectiveFile = new File(tempDir, "/org/apache/tiles/autotag/jsp/test/DoStuffNoBodyTag.java");
+        assertTrue(effectiveFile.exists());
+        effective = new FileInputStream(effectiveFile);
+        assertTrue(IOUtils.contentEquals(effective, expected));
+        effective.close();
+        expected.close();
+
+        FileUtils.deleteDirectory(tempDir);
+    }
+
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-jsp/src/test/resources/org/apache/tiles/autotag/jsp/test/DoStuffNoBodyTag.java b/Java-base/tiles-autotag/src/tiles-autotag-jsp/src/test/resources/org/apache/tiles/autotag/jsp/test/DoStuffNoBodyTag.java
new file mode 100644
index 000000000..291fe66fd
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-jsp/src/test/resources/org/apache/tiles/autotag/jsp/test/DoStuffNoBodyTag.java
@@ -0,0 +1,117 @@
+/*
+ * This file was automatically generated by Apache Tiles Autotag.
+ */
+package org.apache.tiles.autotag.jsp.test;
+
+import java.io.IOException;
+
+import javax.servlet.jsp.JspException;
+import javax.servlet.jsp.tagext.SimpleTagSupport;
+
+import org.apache.tiles.autotag.core.runtime.AutotagRuntime;
+
+/**
+ * Documentation of the DoStuffNoBody class.
+ */
+public class DoStuffNoBodyTag extends SimpleTagSupport {
+
+    /**
+     * The template model.
+     */
+    private org.apache.tiles.autotag.template.DoStuffNoBodyTemplate model = new org.apache.tiles.autotag.template.DoStuffNoBodyTemplate();
+
+    /**
+     * Parameter one.
+     */
+    private java.lang.Double one;
+
+    /**
+     * Parameter two.
+     */
+    private float two;
+
+    /**
+     * Parameter three.
+     */
+    private java.util.Date three;
+
+    /**
+     * Getter for one property.
+     *
+     * @return
+     * Parameter one.
+     */
+    public java.lang.Double getOne() {
+        return one;
+    }
+
+    /**
+     * Setter for one property.
+     *
+     * @param one
+     * Parameter one.
+     */
+    public void setOne(java.lang.Double one) {
+        this.one = one;
+    }
+
+    /**
+     * Getter for two property.
+     *
+     * @return
+     * Parameter two.
+     */
+    public float getTwo() {
+        return two;
+    }
+
+    /**
+     * Setter for two property.
+     *
+     * @param two
+     * Parameter two.
+     */
+    public void setTwo(float two) {
+        this.two = two;
+    }
+
+    /**
+     * Getter for three property.
+     *
+     * @return
+     * Parameter three.
+     */
+    public java.util.Date getThree() {
+        return three;
+    }
+
+    /**
+     * Setter for three property.
+     *
+     * @param three
+     * Parameter three.
+     */
+    public void setThree(java.util.Date three) {
+        this.three = three;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void doTag() throws JspException, IOException {
+        AutotagRuntime<org.apache.tiles.autotag.jsp.test.Request> runtime = new org.apache.tiles.autotag.jsp.test.Runtime();
+        if (runtime instanceof SimpleTagSupport) {
+            SimpleTagSupport tag = (SimpleTagSupport) runtime;
+            tag.setJspContext(getJspContext());
+            tag.setJspBody(getJspBody());
+            tag.setParent(getParent());
+            tag.doTag();
+        }
+        org.apache.tiles.autotag.jsp.test.Request request = runtime.createRequest();        
+        model.execute(
+            one,
+            two,
+            three,
+            request
+        );
+    }
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-jsp/src/test/resources/org/apache/tiles/autotag/jsp/test/DoStuffTag.java b/Java-base/tiles-autotag/src/tiles-autotag-jsp/src/test/resources/org/apache/tiles/autotag/jsp/test/DoStuffTag.java
new file mode 100644
index 000000000..b9fbc0e92
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-jsp/src/test/resources/org/apache/tiles/autotag/jsp/test/DoStuffTag.java
@@ -0,0 +1,119 @@
+/*
+ * This file was automatically generated by Apache Tiles Autotag.
+ */
+package org.apache.tiles.autotag.jsp.test;
+
+import java.io.IOException;
+
+import javax.servlet.jsp.JspException;
+import javax.servlet.jsp.tagext.SimpleTagSupport;
+
+import org.apache.tiles.autotag.core.runtime.ModelBody;
+import org.apache.tiles.autotag.core.runtime.AutotagRuntime;
+
+/**
+ * Documentation of the DoStuff class.
+ */
+public class DoStuffTag extends SimpleTagSupport {
+
+    /**
+     * The template model.
+     */
+    private org.apache.tiles.autotag.template.DoStuffTemplate model = new org.apache.tiles.autotag.template.DoStuffTemplate();
+
+    /**
+     * Parameter one.
+     */
+    private java.lang.String one;
+
+    /**
+     * Parameter two.
+     */
+    private int two;
+
+    /**
+     * Parameter three.
+     */
+    private boolean three;
+
+    /**
+     * Getter for one property.
+     *
+     * @return
+     * Parameter one.
+     */
+    public java.lang.String getOne() {
+        return one;
+    }
+
+    /**
+     * Setter for one property.
+     *
+     * @param one
+     * Parameter one.
+     */
+    public void setOne(java.lang.String one) {
+        this.one = one;
+    }
+
+    /**
+     * Getter for two property.
+     *
+     * @return
+     * Parameter two.
+     */
+    public int getTwo() {
+        return two;
+    }
+
+    /**
+     * Setter for two property.
+     *
+     * @param two
+     * Parameter two.
+     */
+    public void setTwo(int two) {
+        this.two = two;
+    }
+
+    /**
+     * Getter for three property.
+     *
+     * @return
+     * Parameter three.
+     */
+    public boolean isThree() {
+        return three;
+    }
+
+    /**
+     * Setter for three property.
+     *
+     * @param three
+     * Parameter three.
+     */
+    public void setThree(boolean three) {
+        this.three = three;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void doTag() throws JspException, IOException {
+        AutotagRuntime<org.apache.tiles.autotag.jsp.test.Request> runtime = new org.apache.tiles.autotag.jsp.test.Runtime();
+        if (runtime instanceof SimpleTagSupport) {
+            SimpleTagSupport tag = (SimpleTagSupport) runtime;
+            tag.setJspContext(getJspContext());
+            tag.setJspBody(getJspBody());
+            tag.setParent(getParent());
+            tag.doTag();
+        }
+        org.apache.tiles.autotag.jsp.test.Request request = runtime.createRequest();        
+        ModelBody modelBody = runtime.createModelBody();
+        model.execute(
+            one,
+            two,
+            three,
+            request, modelBody
+        );
+    }
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-jsp/src/test/resources/tldtest-jsp.tld b/Java-base/tiles-autotag/src/tiles-autotag-jsp/src/test/resources/tldtest-jsp.tld
new file mode 100644
index 000000000..2db4ddc93
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-jsp/src/test/resources/tldtest-jsp.tld
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- This file was automatically generated by Apache Tiles Autotag. -->
+<taglib
+  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
+  xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  version="2.1">
+   <description>
+   <![CDATA[
+   Test for TLD docs.
+   ]]>
+   </description>
+   <tlib-version>1.2</tlib-version>
+   <short-name>tldtest</short-name>
+   <uri>http://www.initrode.net/tags/test</uri>
+   <tag>
+      <description>
+      <![CDATA[
+      Documentation of the DoStuff class
+      ]]>
+      </description>
+      <name>doStuff</name>
+      <tag-class>org.apache.tiles.autotag.jsp.test.DoStuffTag</tag-class>
+      <body-content>scriptless</body-content>
+      <attribute>
+         <description>
+         <![CDATA[
+         Parameter one.
+         ]]>
+         </description>
+         <name>one</name>
+         <required>true</required>
+         <rtexprvalue>true</rtexprvalue>
+         <type>java.lang.String</type>
+      </attribute>
+      <attribute>
+         <description>
+         <![CDATA[
+         Parameter two.
+         ]]>
+         </description>
+         <name>two</name>
+         <required>false</required>
+         <rtexprvalue>true</rtexprvalue>
+         <type>int</type>
+      </attribute>
+      <attribute>
+         <description>
+         <![CDATA[
+         Parameter three.
+         ]]>
+         </description>
+         <name>three</name>
+         <required>false</required>
+         <rtexprvalue>true</rtexprvalue>
+         <type>long</type>
+      </attribute>
+   </tag>
+   <tag>
+      <description>
+      <![CDATA[
+      Documentation of the DoStuffNoBody class
+      ]]>
+      </description>
+      <name>doStuffNoBody</name>
+      <tag-class>org.apache.tiles.autotag.jsp.test.DoStuffNoBodyTag</tag-class>
+      <body-content>empty</body-content>
+      <attribute>
+         <description>
+         <![CDATA[
+         Parameter one.
+         ]]>
+         </description>
+         <name>one</name>
+         <required>true</required>
+         <rtexprvalue>true</rtexprvalue>
+         <type>java.lang.Double</type>
+      </attribute>
+      <attribute>
+         <description>
+         <![CDATA[
+         Parameter two.
+         ]]>
+         </description>
+         <name>two</name>
+         <required>false</required>
+         <rtexprvalue>true</rtexprvalue>
+         <type>float</type>
+      </attribute>
+      <attribute>
+         <description>
+         <![CDATA[
+         Parameter three.
+         ]]>
+         </description>
+         <name>three</name>
+         <required>false</required>
+         <rtexprvalue>true</rtexprvalue>
+         <type>java.util.Date</type>
+      </attribute>
+   </tag>
+</taglib>
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-velocity/pom.xml b/Java-base/tiles-autotag/src/tiles-autotag-velocity/pom.xml
new file mode 100644
index 000000000..c83f0fde0
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-velocity/pom.xml
@@ -0,0 +1,59 @@
+<?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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <artifactId>tiles-autotag</artifactId>
+    <groupId>org.apache.tiles</groupId>
+    <version>1.3-SNAPSHOT</version>
+  </parent>
+  <groupId>org.apache.tiles</groupId>
+  <artifactId>tiles-autotag-velocity</artifactId>
+  <version>1.3-SNAPSHOT</version>
+  <name>Autotag - Velocity support</name>
+  <description>Module to generate Velocity code to use tag models.</description>
+  <properties>
+        <!-- decrease this whenever possible -->
+        <checkstyle.maxAllowedViolations>1</checkstyle.maxAllowedViolations>
+  </properties>
+  <dependencies>
+  	<dependency>
+  		<groupId>org.apache.tiles</groupId>
+  		<artifactId>tiles-autotag-core</artifactId>
+  	</dependency>
+  	<dependency>
+  		<groupId>junit</groupId>
+  		<artifactId>junit</artifactId>
+  		<scope>test</scope>
+  	</dependency>
+  	<dependency>
+  		<groupId>commons-io</groupId>
+  		<artifactId>commons-io</artifactId>
+  		<scope>test</scope>
+  	</dependency>
+  	<dependency>
+  		<groupId>org.easymock</groupId>
+  		<artifactId>easymock</artifactId>
+  		<scope>test</scope>
+  	</dependency>
+  </dependencies>
+</project>
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-velocity/src/main/java/org/apache/tiles/autotag/velocity/VelocityDirectiveGenerator.java b/Java-base/tiles-autotag/src/tiles-autotag-velocity/src/main/java/org/apache/tiles/autotag/velocity/VelocityDirectiveGenerator.java
new file mode 100644
index 000000000..7edcc332d
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-velocity/src/main/java/org/apache/tiles/autotag/velocity/VelocityDirectiveGenerator.java
@@ -0,0 +1,66 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.velocity;
+
+import java.util.Map;
+
+import org.apache.tiles.autotag.generate.AbstractTemplateClassGenerator;
+import org.apache.tiles.autotag.model.TemplateClass;
+import org.apache.tiles.autotag.model.TemplateSuite;
+import org.apache.velocity.app.VelocityEngine;
+
+/**
+ * Generates a Velocity directive using a template class.
+ *
+ * @version $Rev$ $Date$
+ */
+public class VelocityDirectiveGenerator extends AbstractTemplateClassGenerator {
+
+    /**
+     * Constructor.
+     *
+     * @param velocityEngine The Velocity engine.
+     */
+    public VelocityDirectiveGenerator(VelocityEngine velocityEngine) {
+        super(velocityEngine);
+    }
+
+    @Override
+    protected String getDirectoryName(String packageName,
+            TemplateSuite suite, TemplateClass clazz, Map<String, String> parameters,
+            String runtimeClass, String requestClass) {
+        return packageName.replaceAll("\\.", "/");
+    }
+
+    @Override
+    protected String getFilename(String packageName,
+            TemplateSuite suite, TemplateClass clazz, Map<String, String> parameters,
+            String runtimeClass, String requestClass) {
+        return clazz.getTagClassPrefix() + "Directive.java";
+    }
+
+    @Override
+    protected String getTemplatePath(String packageName,
+            TemplateSuite suite, TemplateClass clazz, Map<String, String> parameters,
+            String runtimeClass, String requestClass) {
+        return "/org/apache/tiles/autotag/velocity/velocityDirective.vm";
+    }
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-velocity/src/main/java/org/apache/tiles/autotag/velocity/VelocityPropertiesGenerator.java b/Java-base/tiles-autotag/src/tiles-autotag-velocity/src/main/java/org/apache/tiles/autotag/velocity/VelocityPropertiesGenerator.java
new file mode 100644
index 000000000..87c1f43ac
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-velocity/src/main/java/org/apache/tiles/autotag/velocity/VelocityPropertiesGenerator.java
@@ -0,0 +1,63 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.velocity;
+
+import java.util.Map;
+
+import org.apache.tiles.autotag.generate.AbstractTemplateSuiteGenerator;
+import org.apache.tiles.autotag.model.TemplateSuite;
+import org.apache.velocity.app.VelocityEngine;
+
+/**
+ * Generates a Velocity properties containing the list of generated user directives for future use.
+ *
+ * @version $Rev$ $Date$
+ */
+public class VelocityPropertiesGenerator extends AbstractTemplateSuiteGenerator {
+
+    /**
+     * Constructor.
+     *
+     * @param velocityEngine The Velocity engine.
+     */
+    public VelocityPropertiesGenerator(VelocityEngine velocityEngine) {
+        super(velocityEngine);
+    }
+
+    @Override
+    protected String getTemplatePath(String packageName,
+            TemplateSuite suite, Map<String, String> parameters) {
+        return "/org/apache/tiles/autotag/velocity/velocityProperties.vm";
+    }
+
+    @Override
+    protected String getFilename(String packageName,
+            TemplateSuite suite, Map<String, String> parameters) {
+        return "velocity.properties";
+    }
+
+    @Override
+    protected String getDirectoryName(String packageName,
+            TemplateSuite suite, Map<String, String> parameters) {
+        return "META-INF/";
+    }
+
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-velocity/src/main/java/org/apache/tiles/autotag/velocity/VelocityTemplateGeneratorFactory.java b/Java-base/tiles-autotag/src/tiles-autotag-velocity/src/main/java/org/apache/tiles/autotag/velocity/VelocityTemplateGeneratorFactory.java
new file mode 100644
index 000000000..bae137df4
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-velocity/src/main/java/org/apache/tiles/autotag/velocity/VelocityTemplateGeneratorFactory.java
@@ -0,0 +1,86 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.velocity;
+
+import org.apache.tiles.autotag.core.OutputLocator;
+import org.apache.tiles.autotag.generate.TemplateGenerator;
+import org.apache.tiles.autotag.generate.TemplateGeneratorBuilder;
+import org.apache.tiles.autotag.generate.TemplateGeneratorFactory;
+import org.apache.velocity.app.VelocityEngine;
+
+/**
+ * Creates a template generator that generates code to build Velocity code
+ * around template classes.
+ *
+ * @version $Rev$ $Date$
+ */
+public class VelocityTemplateGeneratorFactory implements
+        TemplateGeneratorFactory {
+
+    /**
+     * Location of the file.
+     */
+    private OutputLocator classesOutputLocator;
+
+    /**
+     * Location of the file.
+     */
+    private OutputLocator resourcesOutputLocator;
+
+    /**
+     * The Velocity engine.
+     */
+    private VelocityEngine velocityEngine;
+
+    /**
+     * The template generator builder.
+     */
+    private TemplateGeneratorBuilder templateGeneratorBuilder;
+
+    /**
+     * Constructor.
+     *
+     * @param classesOutputLocator The directory where classes will be generated.
+     * @param resourcesOutputLocator The directory where velocity.properties will be written.
+     * @param velocityEngine The Velocity engine.
+     * @param templateGeneratorBuilder The template generator builder.
+     */
+    public VelocityTemplateGeneratorFactory(OutputLocator classesOutputLocator,
+    		OutputLocator resourcesOutputLocator, VelocityEngine velocityEngine,
+            TemplateGeneratorBuilder templateGeneratorBuilder) {
+        this.classesOutputLocator = classesOutputLocator;
+        this.resourcesOutputLocator = resourcesOutputLocator;
+        this.velocityEngine = velocityEngine;
+        this.templateGeneratorBuilder = templateGeneratorBuilder;
+    }
+
+    @Override
+    public TemplateGenerator createTemplateGenerator() {
+        return templateGeneratorBuilder
+                .setClassesOutputLocator(classesOutputLocator)
+                .setResourcesOutputLocator(resourcesOutputLocator)
+                .addResourcesTemplateSuiteGenerator(
+                        new VelocityPropertiesGenerator(velocityEngine))
+                .addClassesTemplateClassGenerator(
+                        new VelocityDirectiveGenerator(velocityEngine)).build();
+    }
+
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-velocity/src/main/java/org/apache/tiles/autotag/velocity/package-info.java b/Java-base/tiles-autotag/src/tiles-autotag-velocity/src/main/java/org/apache/tiles/autotag/velocity/package-info.java
new file mode 100644
index 000000000..a2c9d1873
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-velocity/src/main/java/org/apache/tiles/autotag/velocity/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * Autotag support for Velocity.
+ */
+package org.apache.tiles.autotag.velocity;
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-velocity/src/main/resources/org/apache/tiles/autotag/velocity/velocityDirective.vm b/Java-base/tiles-autotag/src/tiles-autotag-velocity/src/main/resources/org/apache/tiles/autotag/velocity/velocityDirective.vm
new file mode 100644
index 000000000..5889713cc
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-velocity/src/main/resources/org/apache/tiles/autotag/velocity/velocityDirective.vm
@@ -0,0 +1,81 @@
+#*
+ * $Id: tiles-jsp.tld 836180 2009-11-14 14:00:02Z apetrelli $
+ *
+ * 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.
+ *#/*
+ * This file was automatically generated by Apache Tiles Autotag.
+ */
+package ${packageName};
+
+import java.io.IOException;
+import java.io.Writer;
+
+#if(${clazz.hasBody()})
+import org.apache.tiles.autotag.core.runtime.ModelBody;
+#end
+import org.apache.tiles.autotag.core.runtime.AutotagRuntime;
+import org.apache.velocity.context.InternalContextAdapter;
+import org.apache.velocity.runtime.directive.Directive;
+import org.apache.velocity.runtime.parser.node.Node;
+
+/**
+#foreach($line in $stringTool.splitOnNewlines(${clazz.documentation}))
+ * ${line}
+#end
+ */
+public class ${clazz.tagClassPrefix}Directive extends Directive {
+
+    /**
+     * The template model.
+     */
+    private ${clazz.name} model = new ${clazz.name}();
+
+    /** {@inheritDoc} */
+    @Override
+    public String getName() {
+        return "${suite.name}_${clazz.tagName}";
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int getType() {
+        return #if(${clazz.hasBody()})BLOCK#{else}LINE#{end};
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean render(InternalContextAdapter context, Writer writer, Node node)
+            throws IOException {
+        AutotagRuntime<${requestClass}> runtime = new ${runtimeClass}();
+        if (runtime instanceof Directive) {
+            ((Directive) runtime).render(context, writer, node);
+        }
+        ${requestClass} request = runtime.createRequest();
+#if(${clazz.hasBody()})
+        ModelBody modelBody = runtime.createModelBody();
+#end
+        model.execute(
+#foreach($parameter in ${clazz.parameters})
+            runtime.getParameter("${parameter.exportedName}", ${stringTool.getClassToCast(${parameter.type})}.class, $stringTool.getDefaultValue(${parameter.type}, ${parameter.defaultValue})),
+#end
+            request#if(${clazz.hasBody()}), modelBody#end
+
+        );
+        return true;
+    }
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-velocity/src/main/resources/org/apache/tiles/autotag/velocity/velocityProperties.vm b/Java-base/tiles-autotag/src/tiles-autotag-velocity/src/main/resources/org/apache/tiles/autotag/velocity/velocityProperties.vm
new file mode 100644
index 000000000..4fc1bb755
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-velocity/src/main/resources/org/apache/tiles/autotag/velocity/velocityProperties.vm
@@ -0,0 +1,22 @@
+#*
+ * $Id: tiles-jsp.tld 836180 2009-11-14 14:00:02Z apetrelli $
+ *
+ * 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.
+ *## This file was automatically generated by Apache Tiles Autotag.
+userdirective=#foreach($clazz in ${suite.getTemplateClasses()})#if($velocityCount > 1),\
+  #{end}${packageName}.${clazz.tagClassPrefix}Directive#end
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-velocity/src/site/site.xml b/Java-base/tiles-autotag/src/tiles-autotag-velocity/src/site/site.xml
new file mode 100644
index 000000000..0a7d00df4
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-velocity/src/site/site.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+/*
+ * $Id: site.xml 1081442 2011-03-14 16:21:08Z apetrelli $
+ *
+ * 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.
+ */
+-->
+<project name="Apache - Tiles Autotags">
+    <bannerLeft>
+        <name>Apache Software Foundation</name>
+        <src>http://www.apache.org/images/asf-logo.gif</src>
+        <href>http://www.apache.org</href>
+    </bannerLeft>
+    <bannerRight>
+        <name>Apache Tiles&#8482;</name>
+        <src>http://tiles.apache.org/images/logo.png</src>
+        <href>http://tiles.apache.org</href>
+    </bannerRight>
+    <body>
+
+        <links>
+            <item name="Apache" href="http://www.apache.org" />
+            <item name="Tiles" href="http://tiles.apache.org" />
+        </links>
+
+
+        <menu name="Apache Tiles&#8482;">
+            <item
+                   name="Tiles Home"
+                   href="../../index.html"/>
+            <item
+                   name="Tiles Autotag"
+                   href="../index.html"/>
+        </menu>
+
+        <menu ref="modules" />
+        <menu ref="reports" />
+
+    </body>
+</project>
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-velocity/src/test/java/org/apache/tiles/autotag/velocity/VelocityDirectiveGeneratorTest.java b/Java-base/tiles-autotag/src/tiles-autotag-velocity/src/test/java/org/apache/tiles/autotag/velocity/VelocityDirectiveGeneratorTest.java
new file mode 100644
index 000000000..27ece694d
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-velocity/src/test/java/org/apache/tiles/autotag/velocity/VelocityDirectiveGeneratorTest.java
@@ -0,0 +1,145 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.velocity;
+
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.tiles.autotag.core.DirectoryOutputLocator;
+import org.apache.tiles.autotag.core.OutputLocator;
+import org.apache.tiles.autotag.core.runtime.ModelBody;
+import org.apache.tiles.autotag.model.TemplateClass;
+import org.apache.tiles.autotag.model.TemplateMethod;
+import org.apache.tiles.autotag.model.TemplateParameter;
+import org.apache.tiles.autotag.model.TemplateSuite;
+import org.apache.velocity.app.VelocityEngine;
+import org.junit.Test;
+
+/**
+ * Tests {@link VelocityDirectiveGenerator}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class VelocityDirectiveGeneratorTest {
+
+    public static final String REQUEST_CLASS = "org.apache.tiles.autotag.velocity.Request";
+
+    /**
+     * Test method for
+     * {@link VelocityDirectiveGenerator#generate(File, String, TemplateSuite, TemplateClass, java.util.Map)}.
+     * @throws Exception If something goes wrong.
+     */
+    @Test
+    public void testGenerate() throws Exception {
+        Properties props = new Properties();
+        InputStream propsStream = getClass().getResourceAsStream("/org/apache/tiles/autotag/velocity.properties");
+        props.load(propsStream);
+        propsStream.close();
+        VelocityEngine velocityEngine = new VelocityEngine(props);
+
+        VelocityDirectiveGenerator generator = new VelocityDirectiveGenerator(velocityEngine);
+        File tempDir = new File(System.getProperty("java.io.tmpdir"), "autotag");
+        OutputLocator locator = new DirectoryOutputLocator(tempDir);
+        tempDir.deleteOnExit();
+        TemplateSuite suite = new TemplateSuite("tldtest", "Test for TLD docs.");
+
+        List<TemplateParameter> params = new ArrayList<TemplateParameter>();
+        TemplateParameter param = new TemplateParameter("one", "one", "java.lang.String", null, true, false);
+        param.setDocumentation("Parameter one.");
+        params.add(param);
+        param = new TemplateParameter("two", "two", "int", null, false, false);
+        param.setDocumentation("Parameter two.");
+        params.add(param);
+        param = new TemplateParameter("three", "three", "boolean", null, false, false);
+        param.setDocumentation("Parameter three.");
+        params.add(param);
+        param = new TemplateParameter("request", "request", REQUEST_CLASS, null, false, true);
+        param.setDocumentation("The request.");
+        params.add(param);
+        param = new TemplateParameter("modelBody", "modelBody", ModelBody.class.getName(), null, false, false);
+        param.setDocumentation("The body.");
+        params.add(param);
+        TemplateMethod executeMethod = new TemplateMethod("execute", params);
+
+        TemplateClass clazz = new TemplateClass("org.apache.tiles.autotag.template.DoStuffTemplate",
+                "doStuff", "DoStuff", executeMethod);
+        clazz.setDocumentation("Documentation of the DoStuff class.");
+
+        generator.generate(locator, "org.apache.tiles.autotag.velocity.test", suite, clazz, null,
+                           "org.apache.tiles.autotag.velocity.test.Runtime", REQUEST_CLASS);
+
+        InputStream expected = getClass()
+                .getResourceAsStream(
+                        "/org/apache/tiles/autotag/velocity/test/DoStuffDirective.javat");
+        File effectiveFile = new File(tempDir, "/org/apache/tiles/autotag/velocity/test/DoStuffDirective.java");
+        assertTrue(effectiveFile.exists());
+        InputStream effective = new FileInputStream(effectiveFile);
+        assertTrue(IOUtils.contentEquals(effective, expected));
+        effective.close();
+        expected.close();
+
+        suite.addTemplateClass(clazz);
+        params = new ArrayList<TemplateParameter>();
+        param = new TemplateParameter("one", "one", "java.lang.Double", null, true, false);
+        param.setDocumentation("Parameter one.");
+        params.add(param);
+        param = new TemplateParameter("two", "two", "float", null, false, false);
+        param.setDocumentation("Parameter two.");
+        params.add(param);
+        param = new TemplateParameter("three", "three", "java.util.Date", null, false, false);
+        param.setDocumentation("Parameter three.");
+        params.add(param);
+        param = new TemplateParameter("request", "request", REQUEST_CLASS, null, false, true);
+        param.setDocumentation("The request.");
+        params.add(param);
+        executeMethod = new TemplateMethod("execute", params);
+
+        clazz = new TemplateClass("org.apache.tiles.autotag.template.DoStuffNoBodyTemplate",
+                "doStuffNoBody", "DoStuffNoBody", executeMethod);
+        clazz.setDocumentation("Documentation of the DoStuffNoBody class.");
+
+        suite.addTemplateClass(clazz);
+
+        generator.generate(locator, "org.apache.tiles.autotag.velocity.test", suite, clazz, null,
+                           "org.apache.tiles.autotag.velocity.test.Runtime", REQUEST_CLASS);
+
+        expected = getClass()
+                .getResourceAsStream(
+                        "/org/apache/tiles/autotag/velocity/test/DoStuffNoBodyDirective.javat");
+        effectiveFile = new File(tempDir, "/org/apache/tiles/autotag/velocity/test/DoStuffNoBodyDirective.java");
+        assertTrue(effectiveFile.exists());
+        effective = new FileInputStream(effectiveFile);
+        assertTrue(IOUtils.contentEquals(effective, expected));
+        effective.close();
+        expected.close();
+
+        FileUtils.deleteDirectory(tempDir);
+    }
+
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-velocity/src/test/java/org/apache/tiles/autotag/velocity/VelocityPropertiesGeneratorTest.java b/Java-base/tiles-autotag/src/tiles-autotag-velocity/src/test/java/org/apache/tiles/autotag/velocity/VelocityPropertiesGeneratorTest.java
new file mode 100644
index 000000000..6c4df746a
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-velocity/src/test/java/org/apache/tiles/autotag/velocity/VelocityPropertiesGeneratorTest.java
@@ -0,0 +1,130 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.velocity;
+
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.tiles.autotag.core.DirectoryOutputLocator;
+import org.apache.tiles.autotag.core.OutputLocator;
+import org.apache.tiles.autotag.core.runtime.ModelBody;
+import org.apache.tiles.autotag.model.TemplateClass;
+import org.apache.tiles.autotag.model.TemplateMethod;
+import org.apache.tiles.autotag.model.TemplateParameter;
+import org.apache.tiles.autotag.model.TemplateSuite;
+import org.apache.velocity.app.VelocityEngine;
+import org.junit.Test;
+
+/**
+ * Tests {@link VelocityPropertiesGenerator}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class VelocityPropertiesGeneratorTest {
+
+    public static final String REQUEST_CLASS = "org.apache.tiles.autotag.velocity.Request";
+
+    /**
+     * Test method for
+     * {@link org.apache.tiles.autotag.velocity.VelocityPropertiesGenerator
+     * #generate(File, String, TemplateSuite, java.util.Map)}.
+     * @throws Exception If something goes wrong.
+     */
+    @Test
+    public void testGenerate() throws Exception {
+        Properties props = new Properties();
+        InputStream propsStream = getClass().getResourceAsStream("/org/apache/tiles/autotag/velocity.properties");
+        props.load(propsStream);
+        propsStream.close();
+        VelocityEngine velocityEngine = new VelocityEngine(props);
+
+        VelocityPropertiesGenerator generator = new VelocityPropertiesGenerator(velocityEngine);
+        File tempDir = new File(System.getProperty("java.io.tmpdir"), "autotag");
+        OutputLocator locator = new DirectoryOutputLocator(tempDir);
+        tempDir.deleteOnExit();
+        TemplateSuite suite = new TemplateSuite("tldtest", "Test for TLD docs.");
+
+        List<TemplateParameter> params = new ArrayList<TemplateParameter>();
+        TemplateParameter param = new TemplateParameter("one", "one", "java.lang.String", null, true, false);
+        param.setDocumentation("Parameter one.");
+        params.add(param);
+        param = new TemplateParameter("two", "two", "int", null, false, false);
+        param.setDocumentation("Parameter two.");
+        params.add(param);
+        param = new TemplateParameter("three", "three", "long", null, false, false);
+        param.setDocumentation("Parameter three.");
+        params.add(param);
+        param = new TemplateParameter("request", "request", REQUEST_CLASS, null, false, true);
+        param.setDocumentation("The request.");
+        params.add(param);
+        param = new TemplateParameter("modelBody", "modelBody", ModelBody.class.getName(), null, false, false);
+        param.setDocumentation("The body.");
+        params.add(param);
+        TemplateMethod executeMethod = new TemplateMethod("execute", params);
+
+        TemplateClass clazz = new TemplateClass("org.apache.tiles.autotag.template.DoStuffTemplate",
+                "doStuff", "DoStuff", executeMethod);
+        clazz.setDocumentation("Documentation of the DoStuff class");
+
+        suite.addTemplateClass(clazz);
+        params = new ArrayList<TemplateParameter>();
+        param = new TemplateParameter("one", "one", "java.lang.Double", null, true, false);
+        param.setDocumentation("Parameter one.");
+        params.add(param);
+        param = new TemplateParameter("two", "two", "float", null, false, false);
+        param.setDocumentation("Parameter two.");
+        params.add(param);
+        param = new TemplateParameter("three", "three", "java.util.Date", null, false, false);
+        param.setDocumentation("Parameter three.");
+        params.add(param);
+        param = new TemplateParameter("request", "request", REQUEST_CLASS, null, false, true);
+        param.setDocumentation("The request.");
+        params.add(param);
+        executeMethod = new TemplateMethod("execute", params);
+
+        clazz = new TemplateClass("org.apache.tiles.autotag.template.DoStuffNoBodyTemplate",
+                "doStuffNoBody", "DoStuffNoBody", executeMethod);
+        clazz.setDocumentation("Documentation of the DoStuffNoBody class");
+
+        suite.addTemplateClass(clazz);
+
+        generator.generate(locator, "org.apache.tiles.autotag.velocity.test", suite, null);
+
+        InputStream expected = getClass().getResourceAsStream("/velocity.properties.test");
+        File effectiveFile = new File(tempDir, "META-INF/velocity.properties");
+        assertTrue(effectiveFile.exists());
+        InputStream effective = new FileInputStream(effectiveFile);
+        assertTrue(IOUtils.contentEquals(effective, expected));
+        effective.close();
+        expected.close();
+
+        FileUtils.deleteDirectory(tempDir);
+    }
+
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-velocity/src/test/java/org/apache/tiles/autotag/velocity/VelocityTemplateGeneratorFactoryTest.java b/Java-base/tiles-autotag/src/tiles-autotag-velocity/src/test/java/org/apache/tiles/autotag/velocity/VelocityTemplateGeneratorFactoryTest.java
new file mode 100644
index 000000000..779880e8e
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-velocity/src/test/java/org/apache/tiles/autotag/velocity/VelocityTemplateGeneratorFactoryTest.java
@@ -0,0 +1,68 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.velocity;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.isA;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.junit.Assert.assertSame;
+
+import org.apache.tiles.autotag.core.OutputLocator;
+import org.apache.tiles.autotag.generate.TemplateGenerator;
+import org.apache.tiles.autotag.generate.TemplateGeneratorBuilder;
+import org.apache.velocity.app.VelocityEngine;
+import org.junit.Test;
+
+/**
+ * Tests {@link JspTemplateGeneratorFactory}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class VelocityTemplateGeneratorFactoryTest {
+
+    /**
+     * Test method for {@link JspTemplateGeneratorFactory#createTemplateGenerator()}.
+     */
+    @Test
+    public void testCreateTemplateGenerator() {
+        OutputLocator classesOutputLocator = createMock(OutputLocator.class);
+        OutputLocator resourcesOutputLocator = createMock(OutputLocator.class);
+        VelocityEngine velocityEngine = createMock(VelocityEngine.class);
+        TemplateGeneratorBuilder builder = createMock(TemplateGeneratorBuilder.class);
+        TemplateGenerator generator = createMock(TemplateGenerator.class);
+
+        expect(builder.setClassesOutputLocator(classesOutputLocator)).andReturn(builder);
+        expect(builder.setResourcesOutputLocator(resourcesOutputLocator)).andReturn(builder);
+        expect(builder.addResourcesTemplateSuiteGenerator(isA(VelocityPropertiesGenerator.class))).andReturn(builder);
+        expect(builder.addClassesTemplateClassGenerator(isA(VelocityDirectiveGenerator.class))).andReturn(builder);
+        expect(builder.build()).andReturn(generator);
+
+        replay(classesOutputLocator, resourcesOutputLocator, velocityEngine, builder, generator);
+        VelocityTemplateGeneratorFactory factory = new VelocityTemplateGeneratorFactory(
+                classesOutputLocator, resourcesOutputLocator,
+                velocityEngine, builder);
+        assertSame(generator, factory.createTemplateGenerator());
+        verify(classesOutputLocator, resourcesOutputLocator, velocityEngine, builder, generator);
+    }
+
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-velocity/src/test/resources/org/apache/tiles/autotag/velocity/test/DoStuffDirective.javat b/Java-base/tiles-autotag/src/tiles-autotag-velocity/src/test/resources/org/apache/tiles/autotag/velocity/test/DoStuffDirective.javat
new file mode 100644
index 000000000..07c13a06d
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-velocity/src/test/resources/org/apache/tiles/autotag/velocity/test/DoStuffDirective.javat
@@ -0,0 +1,55 @@
+/*
+ * This file was automatically generated by Apache Tiles Autotag.
+ */
+package org.apache.tiles.autotag.velocity.test;
+
+import java.io.IOException;
+import java.io.Writer;
+
+import org.apache.tiles.autotag.core.runtime.ModelBody;
+import org.apache.tiles.autotag.core.runtime.AutotagRuntime;
+import org.apache.velocity.context.InternalContextAdapter;
+import org.apache.velocity.runtime.directive.Directive;
+import org.apache.velocity.runtime.parser.node.Node;
+
+/**
+ * Documentation of the DoStuff class.
+ */
+public class DoStuffDirective extends Directive {
+
+    /**
+     * The template model.
+     */
+    private org.apache.tiles.autotag.template.DoStuffTemplate model = new org.apache.tiles.autotag.template.DoStuffTemplate();
+
+    /** {@inheritDoc} */
+    @Override
+    public String getName() {
+        return "tldtest_doStuff";
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int getType() {
+        return BLOCK;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean render(InternalContextAdapter context, Writer writer, Node node)
+            throws IOException {
+        AutotagRuntime<org.apache.tiles.autotag.velocity.Request> runtime = new org.apache.tiles.autotag.velocity.test.Runtime();
+        if (runtime instanceof Directive) {
+            ((Directive) runtime).render(context, writer, node);
+        }
+        org.apache.tiles.autotag.velocity.Request request = runtime.createRequest();
+        ModelBody modelBody = runtime.createModelBody();
+        model.execute(
+            runtime.getParameter("one", java.lang.String.class, null),
+            runtime.getParameter("two", java.lang.Integer.class, 0),
+            runtime.getParameter("three", java.lang.Boolean.class, false),
+            request, modelBody
+        );
+        return true;
+    }
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-velocity/src/test/resources/org/apache/tiles/autotag/velocity/test/DoStuffNoBodyDirective.javat b/Java-base/tiles-autotag/src/tiles-autotag-velocity/src/test/resources/org/apache/tiles/autotag/velocity/test/DoStuffNoBodyDirective.javat
new file mode 100644
index 000000000..6b766fe07
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-velocity/src/test/resources/org/apache/tiles/autotag/velocity/test/DoStuffNoBodyDirective.javat
@@ -0,0 +1,53 @@
+/*
+ * This file was automatically generated by Apache Tiles Autotag.
+ */
+package org.apache.tiles.autotag.velocity.test;
+
+import java.io.IOException;
+import java.io.Writer;
+
+import org.apache.tiles.autotag.core.runtime.AutotagRuntime;
+import org.apache.velocity.context.InternalContextAdapter;
+import org.apache.velocity.runtime.directive.Directive;
+import org.apache.velocity.runtime.parser.node.Node;
+
+/**
+ * Documentation of the DoStuffNoBody class.
+ */
+public class DoStuffNoBodyDirective extends Directive {
+
+    /**
+     * The template model.
+     */
+    private org.apache.tiles.autotag.template.DoStuffNoBodyTemplate model = new org.apache.tiles.autotag.template.DoStuffNoBodyTemplate();
+
+    /** {@inheritDoc} */
+    @Override
+    public String getName() {
+        return "tldtest_doStuffNoBody";
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int getType() {
+        return LINE;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean render(InternalContextAdapter context, Writer writer, Node node)
+            throws IOException {
+        AutotagRuntime<org.apache.tiles.autotag.velocity.Request> runtime = new org.apache.tiles.autotag.velocity.test.Runtime();
+        if (runtime instanceof Directive) {
+            ((Directive) runtime).render(context, writer, node);
+        }
+        org.apache.tiles.autotag.velocity.Request request = runtime.createRequest();
+        model.execute(
+            runtime.getParameter("one", java.lang.Double.class, null),
+            runtime.getParameter("two", java.lang.Float.class, 0.0f),
+            runtime.getParameter("three", java.util.Date.class, null),
+            request
+        );
+        return true;
+    }
+}
diff --git a/Java-base/tiles-autotag/src/tiles-autotag-velocity/src/test/resources/velocity.properties.test b/Java-base/tiles-autotag/src/tiles-autotag-velocity/src/test/resources/velocity.properties.test
new file mode 100644
index 000000000..4d4051adf
--- /dev/null
+++ b/Java-base/tiles-autotag/src/tiles-autotag-velocity/src/test/resources/velocity.properties.test
@@ -0,0 +1,3 @@
+# This file was automatically generated by Apache Tiles Autotag.
+userdirective=org.apache.tiles.autotag.velocity.test.DoStuffDirective,\
+  org.apache.tiles.autotag.velocity.test.DoStuffNoBodyDirective
\ No newline at end of file
diff --git a/Java-base/tiles/Dockerfile b/Java-base/tiles/Dockerfile
new file mode 100644
index 000000000..e208c4890
--- /dev/null
+++ b/Java-base/tiles/Dockerfile
@@ -0,0 +1,28 @@
+FROM ubuntu:22.04
+
+RUN export DEBIAN_FRONTEND=noninteractive \
+    && apt-get update \
+    && apt-get install -y software-properties-common \
+    && add-apt-repository ppa:deadsnakes/ppa \
+    && apt-get update \
+    && apt-get install -y \
+        build-essential \
+        git \
+        vim \
+        jq \
+    && apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/list/*
+
+RUN apt-get -y install sudo \
+      openjdk-8-jdk \
+      maven
+
+RUN bash -c "echo 2 | update-alternatives --config java"
+
+COPY src /workspace
+WORKDIR /workspace
+
+RUN mvn install -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false
+
+RUN mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100
+
+ENV TZ=Asia/Seoul
diff --git a/Java-base/tiles/src/FREEMARKER-LICENSE.txt b/Java-base/tiles/src/FREEMARKER-LICENSE.txt
new file mode 100644
index 000000000..ca617cb65
--- /dev/null
+++ b/Java-base/tiles/src/FREEMARKER-LICENSE.txt
@@ -0,0 +1,46 @@
+FreeMarker 1.x was released under the LGPL license. Later, by community
+consensus, we have switched over to a BSD-style license. As of FreeMarker
+2.2pre1, the original author, Benjamin Geer, has relinquished the copyright in
+behalf of Visigoth Software Society. The current copyright holder is the
+Visigoth Software Society.
+
+------------------------------------------------------------------------------
+Copyright (c) 2003 The Visigoth Software Society. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1.  Redistributions of source code must retain the above copyright notice,
+    this list of conditions and the following disclaimer.
+
+2.  The end-user documentation included with the redistribution, if any, must
+    include the following acknowlegement:
+      "This product includes software developed by the
+      Visigoth Software Society (http://www.visigoths.org/)."
+    Alternately, this acknowlegement may appear in the software itself, if and
+    wherever such third-party acknowlegements normally appear.
+
+3.  Neither the name "FreeMarker", "Visigoth", nor any of the names of the
+    project contributors may be used to endorse or promote products derived
+    from this software without prior written permission. For written
+    permission, please contact visigoths@visigoths.org.
+
+4.  Products derived from this software may not be called "FreeMarker" or
+    "Visigoth" nor may "FreeMarker" or "Visigoth" appear in their names
+    without prior written permission of the Visigoth Software Society.
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+VISIGOTH SOFTWARE SOCIETY OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+------------------------------------------------------------------------------
+
+This software consists of voluntary contributions made by many individuals on
+behalf of the Visigoth Software Society. For more information on the Visigoth
+Software Society, please see http://www.visigoths.org/
diff --git a/Java-base/tiles/src/JAVASSIST-LICENSE.html b/Java-base/tiles/src/JAVASSIST-LICENSE.html
new file mode 100644
index 000000000..65d6611ed
--- /dev/null
+++ b/Java-base/tiles/src/JAVASSIST-LICENSE.html
@@ -0,0 +1,372 @@
+<HTML>
+<HEAD>
+<TITLE>Javassist License</TITLE>
+<META http-equiv=Content-Type content="text/html; charset=iso-8859-1">
+<META content="MSHTML 5.50.4916.2300" name=GENERATOR></HEAD>
+
+<BODY text=#000000 vLink=#551a8b aLink=#ff0000 link=#0000ee bgColor=#ffffff>
+<CENTER><B><FONT size=+2>MOZILLA PUBLIC LICENSE</FONT></B> <BR><B>Version 
+1.1</B> 
+<P>
+<HR width="20%">
+</CENTER>
+<P><B>1. Definitions.</B> 
+<UL><B>1.0.1. "Commercial Use" </B>means distribution or otherwise making the 
+  Covered Code available to a third party. 
+  <P><B>1.1. ''Contributor''</B> means each entity that creates or contributes 
+  to the creation of Modifications. 
+  <P><B>1.2. ''Contributor Version''</B> means the combination of the Original 
+  Code, prior Modifications used by a Contributor, and the Modifications made by 
+  that particular Contributor. 
+  <P><B>1.3. ''Covered Code''</B> means the Original Code or Modifications or 
+  the combination of the Original Code and Modifications, in each case including 
+  portions thereof<B>.</B> 
+  <P><B>1.4. ''Electronic Distribution Mechanism''</B> means a mechanism 
+  generally accepted in the software development community for the electronic 
+  transfer of data. 
+  <P><B>1.5. ''Executable''</B> means Covered Code in any form other than Source 
+  Code. 
+  <P><B>1.6. ''Initial Developer''</B> means the individual or entity identified 
+  as the Initial Developer in the Source Code notice required by <B>Exhibit 
+  A</B>. 
+  <P><B>1.7. ''Larger Work''</B> means a work which combines Covered Code or 
+  portions thereof with code not governed by the terms of this License. 
+  <P><B>1.8. ''License''</B> means this document. 
+  <P><B>1.8.1. "Licensable"</B> means having the right to grant, to the maximum 
+  extent possible, whether at the time of the initial grant or subsequently 
+  acquired, any and all of the rights conveyed herein. 
+  <P><B>1.9. ''Modifications''</B> means any addition to or deletion from the 
+  substance or structure of either the Original Code or any previous 
+  Modifications. When Covered Code is released as a series of files, a 
+  Modification is: 
+  <UL><B>A.</B> Any addition to or deletion from the contents of a file 
+    containing Original Code or previous Modifications. 
+    <P><B>B.</B> Any new file that contains any part of the Original Code or 
+    previous Modifications. <BR>&nbsp;</P></UL><B>1.10. ''Original Code''</B> 
+  means Source Code of computer software code which is described in the Source 
+  Code notice required by <B>Exhibit A</B> as Original Code, and which, at the 
+  time of its release under this License is not already Covered Code governed by 
+  this License. 
+  <P><B>1.10.1. "Patent Claims"</B> means any patent claim(s), now owned or 
+  hereafter acquired, including without limitation,&nbsp; method, process, and 
+  apparatus claims, in any patent Licensable by grantor. 
+  <P><B>1.11. ''Source Code''</B> means the preferred form of the Covered Code 
+  for making modifications to it, including all modules it contains, plus any 
+  associated interface definition files, scripts used to control compilation and 
+  installation of an Executable, or source code differential comparisons against 
+  either the Original Code or another well known, available Covered Code of the 
+  Contributor's choice. The Source Code can be in a compressed or archival form, 
+  provided the appropriate decompression or de-archiving software is widely 
+  available for no charge. 
+  <P><B>1.12. "You'' (or "Your")&nbsp;</B> means an individual or a legal entity 
+  exercising rights under, and complying with all of the terms of, this License 
+  or a future version of this License issued under Section 6.1. For legal 
+  entities, "You'' includes any entity which controls, is controlled by, or is 
+  under common control with You. For purposes of this definition, "control'' 
+  means (a) the power, direct or indirect, to cause the direction or management 
+  of such entity, whether by contract or otherwise, or (b) ownership of more 
+  than fifty percent (50%) of the outstanding shares or beneficial ownership of 
+  such entity.</P></UL><B>2. Source Code License.</B> 
+<UL><B>2.1. The Initial Developer Grant.</B> <BR>The Initial Developer hereby 
+  grants You a world-wide, royalty-free, non-exclusive license, subject to third 
+  party intellectual property claims: 
+  <UL><B>(a)</B>&nbsp;<B> </B>under intellectual property rights (other than 
+    patent or trademark) Licensable by Initial Developer to use, reproduce, 
+    modify, display, perform, sublicense and distribute the Original Code (or 
+    portions thereof) with or without Modifications, and/or as part of a Larger 
+    Work; and 
+    <P><B>(b)</B> under Patents Claims infringed by the making, using or selling 
+    of Original Code, to make, have made, use, practice, sell, and offer for 
+    sale, and/or otherwise dispose of the Original Code (or portions thereof). 
+    <UL>
+      <UL></UL></UL><B>(c) </B>the licenses granted in this Section 2.1(a) and (b) 
+    are effective on the date Initial Developer first distributes Original Code 
+    under the terms of this License. 
+    <P><B>(d) </B>Notwithstanding Section 2.1(b) above, no patent license is 
+    granted: 1) for code that You delete from the Original Code; 2) separate 
+    from the Original Code;&nbsp; or 3) for infringements caused by: i) the 
+    modification of the Original Code or ii) the combination of the Original 
+    Code with other software or devices. <BR>&nbsp;</P></UL><B>2.2. Contributor 
+  Grant.</B> <BR>Subject to third party intellectual property claims, each 
+  Contributor hereby grants You a world-wide, royalty-free, non-exclusive 
+  license 
+  <UL> <BR><B>(a)</B>&nbsp;<B> </B>under intellectual property rights (other 
+    than patent or trademark) Licensable by Contributor, to use, reproduce, 
+    modify, display, perform, sublicense and distribute the Modifications 
+    created by such Contributor (or portions thereof) either on an unmodified 
+    basis, with other Modifications, as Covered Code and/or as part of a Larger 
+    Work; and 
+    <P><B>(b)</B> under Patent Claims infringed by the making, using, or selling 
+    of&nbsp; Modifications made by that Contributor either alone and/or in<FONT 
+    color=#000000> combination with its Contributor Version (or portions of such 
+    combination), to make, use, sell, offer for sale, have made, and/or 
+    otherwise dispose of: 1) Modifications made by that Contributor (or portions 
+    thereof); and 2) the combination of&nbsp; Modifications made by that 
+    Contributor with its Contributor Version (or portions of such 
+    combination).</FONT> 
+    <P><B>(c) </B>the licenses granted in Sections 2.2(a) and 2.2(b) are 
+    effective on the date Contributor first makes Commercial Use of the Covered 
+    Code. 
+    <P><B>(d)&nbsp;</B>&nbsp;&nbsp; Notwithstanding Section 2.2(b) above, no 
+    patent license is granted: 1) for any code that Contributor has deleted from 
+    the Contributor Version; 2)&nbsp; separate from the Contributor 
+    Version;&nbsp; 3)&nbsp; for infringements caused by: i) third party 
+    modifications of Contributor Version or ii)&nbsp; the combination of 
+    Modifications made by that Contributor with other software&nbsp; (except as 
+    part of the Contributor Version) or other devices; or 4) under Patent Claims 
+    infringed by Covered Code in the absence of Modifications made by that 
+    Contributor.</P></UL></UL>
+<P><BR><B>3. Distribution Obligations.</B> 
+<UL><B>3.1. Application of License.</B> <BR>The Modifications which You create 
+  or to which You contribute are governed by the terms of this License, 
+  including without limitation Section <B>2.2</B>. The Source Code version of 
+  Covered Code may be distributed only under the terms of this License or a 
+  future version of this License released under Section <B>6.1</B>, and You must 
+  include a copy of this License with every copy of the Source Code You 
+  distribute. You may not offer or impose any terms on any Source Code version 
+  that alters or restricts the applicable version of this License or the 
+  recipients' rights hereunder. However, You may include an additional document 
+  offering the additional rights described in Section <B>3.5</B>. 
+  <P><B>3.2. Availability of Source Code.</B> <BR>Any Modification which You 
+  create or to which You contribute must be made available in Source Code form 
+  under the terms of this License either on the same media as an Executable 
+  version or via an accepted Electronic Distribution Mechanism to anyone to whom 
+  you made an Executable version available; and if made available via Electronic 
+  Distribution Mechanism, must remain available for at least twelve (12) months 
+  after the date it initially became available, or at least six (6) months after 
+  a subsequent version of that particular Modification has been made available 
+  to such recipients. You are responsible for ensuring that the Source Code 
+  version remains available even if the Electronic Distribution Mechanism is 
+  maintained by a third party. 
+  <P><B>3.3. Description of Modifications.</B> <BR>You must cause all Covered 
+  Code to which You contribute to contain a file documenting the changes You 
+  made to create that Covered Code and the date of any change. You must include 
+  a prominent statement that the Modification is derived, directly or 
+  indirectly, from Original Code provided by the Initial Developer and including 
+  the name of the Initial Developer in (a) the Source Code, and (b) in any 
+  notice in an Executable version or related documentation in which You describe 
+  the origin or ownership of the Covered Code. 
+  <P><B>3.4. Intellectual Property Matters</B> 
+  <UL><B>(a) Third Party Claims</B>. <BR>If Contributor has knowledge that a 
+    license under a third party's intellectual property rights is required to 
+    exercise the rights granted by such Contributor under Sections 2.1 or 2.2, 
+    Contributor must include a text file with the Source Code distribution 
+    titled "LEGAL'' which describes the claim and the party making the claim in 
+    sufficient detail that a recipient will know whom to contact. If Contributor 
+    obtains such knowledge after the Modification is made available as described 
+    in Section 3.2, Contributor shall promptly modify the LEGAL file in all 
+    copies Contributor makes available thereafter and shall take other steps 
+    (such as notifying appropriate mailing lists or newsgroups) reasonably 
+    calculated to inform those who received the Covered Code that new knowledge 
+    has been obtained. 
+    <P><B>(b) Contributor APIs</B>. <BR>If Contributor's Modifications include 
+    an application programming interface and Contributor has knowledge of patent 
+    licenses which are reasonably necessary to implement that API, Contributor 
+    must also include this information in the LEGAL file. 
+  <BR>&nbsp;</P></UL>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
+  <B>(c)&nbsp;&nbsp;&nbsp; Representations.</B> 
+  <UL>Contributor represents that, except as disclosed pursuant to Section 
+    3.4(a) above, Contributor believes that Contributor's Modifications are 
+    Contributor's original creation(s) and/or Contributor has sufficient rights 
+    to grant the rights conveyed by this License.</UL>
+  <P><BR><B>3.5. Required Notices.</B> <BR>You must duplicate the notice in 
+  <B>Exhibit A</B> in each file of the Source Code.&nbsp; If it is not possible 
+  to put such notice in a particular Source Code file due to its structure, then 
+  You must include such notice in a location (such as a relevant directory) 
+  where a user would be likely to look for such a notice.&nbsp; If You created 
+  one or more Modification(s) You may add your name as a Contributor to the 
+  notice described in <B>Exhibit A</B>.&nbsp; You must also duplicate this 
+  License in any documentation for the Source Code where You describe 
+  recipients' rights or ownership rights relating to Covered Code.&nbsp; You may 
+  choose to offer, and to charge a fee for, warranty, support, indemnity or 
+  liability obligations to one or more recipients of Covered Code. However, You 
+  may do so only on Your own behalf, and not on behalf of the Initial Developer 
+  or any Contributor. You must make it absolutely clear than any such warranty, 
+  support, indemnity or liability obligation is offered by You alone, and You 
+  hereby agree to indemnify the Initial Developer and every Contributor for any 
+  liability incurred by the Initial Developer or such Contributor as a result of 
+  warranty, support, indemnity or liability terms You offer. 
+  <P><B>3.6. Distribution of Executable Versions.</B> <BR>You may distribute 
+  Covered Code in Executable form only if the requirements of Section 
+  <B>3.1-3.5</B> have been met for that Covered Code, and if You include a 
+  notice stating that the Source Code version of the Covered Code is available 
+  under the terms of this License, including a description of how and where You 
+  have fulfilled the obligations of Section <B>3.2</B>. The notice must be 
+  conspicuously included in any notice in an Executable version, related 
+  documentation or collateral in which You describe recipients' rights relating 
+  to the Covered Code. You may distribute the Executable version of Covered Code 
+  or ownership rights under a license of Your choice, which may contain terms 
+  different from this License, provided that You are in compliance with the 
+  terms of this License and that the license for the Executable version does not 
+  attempt to limit or alter the recipient's rights in the Source Code version 
+  from the rights set forth in this License. If You distribute the Executable 
+  version under a different license You must make it absolutely clear that any 
+  terms which differ from this License are offered by You alone, not by the 
+  Initial Developer or any Contributor. You hereby agree to indemnify the 
+  Initial Developer and every Contributor for any liability incurred by the 
+  Initial Developer or such Contributor as a result of any such terms You offer. 
+
+  <P><B>3.7. Larger Works.</B> <BR>You may create a Larger Work by combining 
+  Covered Code with other code not governed by the terms of this License and 
+  distribute the Larger Work as a single product. In such a case, You must make 
+  sure the requirements of this License are fulfilled for the Covered 
+Code.</P></UL><B>4. Inability to Comply Due to Statute or Regulation.</B> 
+<UL>If it is impossible for You to comply with any of the terms of this 
+  License with respect to some or all of the Covered Code due to statute, 
+  judicial order, or regulation then You must: (a) comply with the terms of this 
+  License to the maximum extent possible; and (b) describe the limitations and 
+  the code they affect. Such description must be included in the LEGAL file 
+  described in Section <B>3.4</B> and must be included with all distributions of 
+  the Source Code. Except to the extent prohibited by statute or regulation, 
+  such description must be sufficiently detailed for a recipient of ordinary 
+  skill to be able to understand it.</UL><B>5. Application of this License.</B> 
+<UL>This License applies to code to which the Initial Developer has attached 
+  the notice in <B>Exhibit A</B> and to related Covered Code.</UL><B>6. Versions 
+of the License.</B> 
+<UL><B>6.1. New Versions</B>. <BR>Netscape Communications Corporation 
+  (''Netscape'') may publish revised and/or new versions of the License from 
+  time to time. Each version will be given a distinguishing version number. 
+  <P><B>6.2. Effect of New Versions</B>. <BR>Once Covered Code has been 
+  published under a particular version of the License, You may always continue 
+  to use it under the terms of that version. You may also choose to use such 
+  Covered Code under the terms of any subsequent version of the License 
+  published by Netscape. No one other than Netscape has the right to modify the 
+  terms applicable to Covered Code created under this License. 
+  <P><B>6.3. Derivative Works</B>. <BR>If You create or use a modified version 
+  of this License (which you may only do in order to apply it to code which is 
+  not already Covered Code governed by this License), You must (a) rename Your 
+  license so that the phrases ''Mozilla'', ''MOZILLAPL'', ''MOZPL'', 
+  ''Netscape'', "MPL", ''NPL'' or any confusingly similar phrase do not appear 
+  in your license (except to note that your license differs from this License) 
+  and (b) otherwise make it clear that Your version of the license contains 
+  terms which differ from the Mozilla Public License and Netscape Public 
+  License. (Filling in the name of the Initial Developer, Original Code or 
+  Contributor in the notice described in <B>Exhibit A</B> shall not of 
+  themselves be deemed to be modifications of this License.)</P></UL><B>7. 
+DISCLAIMER OF WARRANTY.</B> 
+<UL>COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS'' BASIS, WITHOUT 
+  WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT 
+  LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, 
+  FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE 
+  QUALITY AND PERFORMANCE OF THE COVERED CODE IS WITH YOU. SHOULD ANY COVERED 
+  CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANY 
+  OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR 
+  CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS 
+  LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS 
+  DISCLAIMER.</UL><B>8. TERMINATION.</B> 
+<UL><B>8.1.&nbsp; </B>This License and the rights granted hereunder will 
+  terminate automatically if You fail to comply with terms herein and fail to 
+  cure such breach within 30 days of becoming aware of the breach. All 
+  sublicenses to the Covered Code which are properly granted shall survive any 
+  termination of this License. Provisions which, by their nature, must remain in 
+  effect beyond the termination of this License shall survive. 
+  <P><B>8.2.&nbsp; </B>If You initiate litigation by asserting a patent 
+  infringement claim (excluding declatory judgment actions) against Initial 
+  Developer or a Contributor (the Initial Developer or Contributor against whom 
+  You file such action is referred to as "Participant")&nbsp; alleging that: 
+  <P><B>(a)&nbsp; </B>such Participant's Contributor Version directly or 
+  indirectly infringes any patent, then any and all rights granted by such 
+  Participant to You under Sections 2.1 and/or 2.2 of this License shall, upon 
+  60 days notice from Participant terminate prospectively, unless if within 60 
+  days after receipt of notice You either: (i)&nbsp; agree in writing to pay 
+  Participant a mutually agreeable reasonable royalty for Your past and future 
+  use of Modifications made by such Participant, or (ii) withdraw Your 
+  litigation claim with respect to the Contributor Version against such 
+  Participant.&nbsp; If within 60 days of notice, a reasonable royalty and 
+  payment arrangement are not mutually agreed upon in writing by the parties or 
+  the litigation claim is not withdrawn, the rights granted by Participant to 
+  You under Sections 2.1 and/or 2.2 automatically terminate at the expiration of 
+  the 60 day notice period specified above. 
+  <P><B>(b)</B>&nbsp; any software, hardware, or device, other than such 
+  Participant's Contributor Version, directly or indirectly infringes any 
+  patent, then any rights granted to You by such Participant under Sections 
+  2.1(b) and 2.2(b) are revoked effective as of the date You first made, used, 
+  sold, distributed, or had made, Modifications made by that Participant. 
+  <P><B>8.3.&nbsp; </B>If You assert a patent infringement claim against 
+  Participant alleging that such Participant's Contributor Version directly or 
+  indirectly infringes any patent where such claim is resolved (such as by 
+  license or settlement) prior to the initiation of patent infringement 
+  litigation, then the reasonable value of the licenses granted by such 
+  Participant under Sections 2.1 or 2.2 shall be taken into account in 
+  determining the amount or value of any payment or license. 
+  <P><B>8.4.</B>&nbsp; In the event of termination under Sections 8.1 or 8.2 
+  above,&nbsp; all end user license agreements (excluding distributors and 
+  resellers) which have been validly granted by You or any distributor hereunder 
+  prior to termination shall survive termination.</P></UL><B>9. LIMITATION OF 
+LIABILITY.</B> 
+<UL>UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT (INCLUDING 
+  NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL DEVELOPER, ANY 
+  OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, OR ANY SUPPLIER OF ANY 
+  OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT, SPECIAL, 
+  INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT 
+  LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR 
+  MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH 
+  PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS 
+  LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL 
+  INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW 
+  PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR 
+  LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS EXCLUSION AND 
+  LIMITATION MAY NOT APPLY TO YOU.</UL><B>10. U.S. GOVERNMENT END USERS.</B> 
+<UL>The Covered Code is a ''commercial item,'' as that term is defined in 48 
+  C.F.R. 2.101 (Oct. 1995), consisting of ''commercial computer software'' and 
+  ''commercial computer software documentation,'' as such terms are used in 48 
+  C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 
+  227.7202-1 through 227.7202-4 (June 1995), all U.S. Government End Users 
+  acquire Covered Code with only those rights set forth herein.</UL><B>11. 
+MISCELLANEOUS.</B> 
+<UL>This License represents the complete agreement concerning subject matter 
+  hereof. If any provision of this License is held to be unenforceable, such 
+  provision shall be reformed only to the extent necessary to make it 
+  enforceable. This License shall be governed by California law provisions 
+  (except to the extent applicable law, if any, provides otherwise), excluding 
+  its conflict-of-law provisions. With respect to disputes in which at least one 
+  party is a citizen of, or an entity chartered or registered to do business in 
+  the United States of America, any litigation relating to this License shall be 
+  subject to the jurisdiction of the Federal Courts of the Northern District of 
+  California, with venue lying in Santa Clara County, California, with the 
+  losing party responsible for costs, including without limitation, court costs 
+  and reasonable attorneys' fees and expenses. The application of the United 
+  Nations Convention on Contracts for the International Sale of Goods is 
+  expressly excluded. Any law or regulation which provides that the language of 
+  a contract shall be construed against the drafter shall not apply to this 
+  License.</UL><B>12. RESPONSIBILITY FOR CLAIMS.</B> 
+<UL>As between Initial Developer and the Contributors, each party is 
+  responsible for claims and damages arising, directly or indirectly, out of its 
+  utilization of rights under this License and You agree to work with Initial 
+  Developer and Contributors to distribute such responsibility on an equitable 
+  basis. Nothing herein is intended or shall be deemed to constitute any 
+  admission of liability.</UL><B>13. MULTIPLE-LICENSED CODE.</B> 
+<UL>Initial Developer may designate portions of the Covered Code as 
+  �Multiple-Licensed?.&nbsp; �Multiple-Licensed? means that the Initial 
+  Developer permits you to utilize portions of the Covered Code under Your 
+  choice of the MPL or the alternative licenses, if any, specified by the 
+  Initial Developer in the file described in Exhibit A.</UL>
+<P><BR><B>EXHIBIT A -Mozilla Public License.</B> 
+<UL>The contents of this file are subject to the Mozilla Public License 
+  Version 1.1 (the "License"); you may not use this file except in compliance 
+  with the License. You may obtain a copy of the License at 
+  <BR>http://www.mozilla.org/MPL/ 
+  <P>Software distributed under the License is distributed on an "AS IS" basis, 
+  WITHOUT WARRANTY OF <BR>ANY KIND, either express or implied. See the License 
+  for the specific language governing rights and <BR>limitations under the 
+  License. 
+  <P>The Original Code is Javassist. 
+  <P>The Initial Developer of the Original Code is Shigeru Chiba. 
+  Portions created by the Initial Developer are<BR>&nbsp;
+  Copyright (C) 1999-2008 Shigeru Chiba. All Rights Reserved. 
+  <P>Contributor(s): ______________________________________. 
+
+  <P>Alternatively, the contents of this file may be used under the terms of
+  the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+  in which case the provisions of the LGPL are applicable instead
+  of those above. If you wish to allow use of your version of this file only
+  under the terms of the LGPL, and not to allow others to
+  use your version of this file under the terms of the MPL, indicate your
+  decision by deleting the provisions above and replace them with the notice
+  and other provisions required by the LGPL. If you do not delete
+  the provisions above, a recipient may use your version of this file under
+  the terms of either the MPL or the LGPL.
+
+  <P></P></UL>
+</BODY>
+</HTML>
diff --git a/Java-base/tiles/src/LICENSE.txt b/Java-base/tiles/src/LICENSE.txt
new file mode 100644
index 000000000..d64569567
--- /dev/null
+++ b/Java-base/tiles/src/LICENSE.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/Java-base/tiles/src/NOTICE.txt b/Java-base/tiles/src/NOTICE.txt
new file mode 100644
index 000000000..c622f7a84
--- /dev/null
+++ b/Java-base/tiles/src/NOTICE.txt
@@ -0,0 +1,15 @@
+   Apache Tiles
+   Copyright 1999-2012 The Apache Software Foundation
+
+   This product includes software developed at
+   The Apache Software Foundation (http://www.apache.org/).
+
+   The binary distribution contains software developed by:
+
+   SpringSource: http://www.springsource.com/
+   Visigoth Software Society (Freemarker): http://freemarker.org/
+   OpenSymphony (OGNL): http://www.opensymphony.com/ognl/
+   Codehaus (MVEL): http://mvel.codehaus.org/
+   JBoss (Javassist): http://jboss.org/javassist/
+   Sam Pullara (Mustache Java): https://github.com/spullara/mustache.java/
+
diff --git a/Java-base/tiles/src/OGNL-LICENSE.txt b/Java-base/tiles/src/OGNL-LICENSE.txt
new file mode 100644
index 000000000..43bafbbb5
--- /dev/null
+++ b/Java-base/tiles/src/OGNL-LICENSE.txt
@@ -0,0 +1,50 @@
+/* ====================================================================
+ * The OpenSymphony Software License, Version 1.1
+ *
+ * (this license is derived and fully compatible with the Apache Software
+ * License - see http://www.apache.org/LICENSE.txt)
+ *
+ * Copyright (c) 2001-2004 The OpenSymphony Group. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        OpenSymphony Group (http://www.opensymphony.com/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "OpenSymphony" and "The OpenSymphony Group"
+ *    must not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written
+ *    permission, please contact license@opensymphony.com .
+ *
+ * 5. Products derived from this software may not be called "OpenSymphony"
+ *    or "OGNL", nor may "OpenSymphony" or "OGNL" appear in their
+ *    name, without prior written permission of the OpenSymphony Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ */
diff --git a/Java-base/tiles/src/SLF4J-LICENSE.txt b/Java-base/tiles/src/SLF4J-LICENSE.txt
new file mode 100644
index 000000000..f5ecafa00
--- /dev/null
+++ b/Java-base/tiles/src/SLF4J-LICENSE.txt
@@ -0,0 +1,21 @@
+Copyright (c) 2004-2008 QOS.ch
+All rights reserved.
+
+Permission is hereby granted, free  of charge, to any person obtaining
+a  copy  of this  software  and  associated  documentation files  (the
+"Software"), to  deal in  the Software without  restriction, including
+without limitation  the rights to  use, copy, modify,  merge, publish,
+distribute,  sublicense, and/or sell  copies of  the Software,  and to
+permit persons to whom the Software  is furnished to do so, subject to
+the following conditions:
+
+The  above  copyright  notice  and  this permission  notice  shall  be
+included in all copies or substantial portions of the Software.
+
+THE  SOFTWARE IS  PROVIDED  "AS  IS", WITHOUT  WARRANTY  OF ANY  KIND,
+EXPRESS OR  IMPLIED, INCLUDING  BUT NOT LIMITED  TO THE  WARRANTIES OF
+MERCHANTABILITY,    FITNESS    FOR    A   PARTICULAR    PURPOSE    AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE,  ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/Java-base/tiles/src/assembly/pom.xml b/Java-base/tiles/src/assembly/pom.xml
new file mode 100644
index 000000000..53ff030b9
--- /dev/null
+++ b/Java-base/tiles/src/assembly/pom.xml
@@ -0,0 +1,203 @@
+<?xml version="1.0"?>
+<!--
+    $Id$
+
+    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.
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.apache.tiles</groupId>
+  <artifactId>tiles-assembly</artifactId>
+  <packaging>pom</packaging>
+  <name>Tiles Assembly</name>
+  <description>Tiles Assembly: assembles artifact to produce distributions.
+  </description>
+
+  <parent>
+    <groupId>org.apache.tiles</groupId>
+    <artifactId>tiles-parent</artifactId>
+    <version>3.1-SNAPSHOT</version>
+  </parent>
+
+  <scm>
+    <connection>scm:svn:http://svn.apache.org/repos/asf/tiles/framework/trunk/assembly</connection>
+    <developerConnection>scm:svn:https://svn.apache.org/repos/asf/tiles/framework/trunk/assembly</developerConnection>
+    <url>http://svn.apache.org/viewcvs.cgi/tiles/framework/trunk/assembly</url>
+  </scm>
+
+  <build>
+    <plugins>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-assembly-plugin</artifactId>
+          <version>2.2-beta-4</version>
+        <configuration>
+          <descriptors>
+            <descriptor>src/main/assembly/bin.xml</descriptor>
+            <descriptor>src/main/assembly/docs.xml</descriptor>
+            <descriptor>src/main/assembly/src.xml</descriptor>
+          </descriptors>
+          <finalName>tiles-${project.version}</finalName>
+          <outputDirectory>target/assembly/out</outputDirectory>
+          <workDirectory>target/assembly/work</workDirectory>
+          <tarLongFileMode>gnu</tarLongFileMode>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <profiles>
+    <profile>
+      <id>apache-release</id>
+      <build>
+        <plugins>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-assembly-plugin</artifactId>
+            <version>3.1.0</version>
+            <executions>
+              <execution>
+                <id>make-assembly</id>
+                <goals>
+                  <goal>single</goal>
+                </goals>
+                <phase>package</phase>
+              </execution>
+            </executions>
+            <configuration>
+              <descriptors>
+                <descriptor>src/main/assembly/bin.xml</descriptor>
+                <descriptor>src/main/assembly/docs.xml</descriptor>
+                <descriptor>src/main/assembly/src.xml</descriptor>
+              </descriptors>
+              <tarLongFileMode>gnu</tarLongFileMode>
+            </configuration>
+          </plugin>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-deploy-plugin</artifactId>
+            <configuration>
+              <skip>true</skip>
+            </configuration>
+          </plugin>
+          <plugin>
+            <groupId>net.nicoulaj.maven.plugins</groupId>
+            <artifactId>checksum-maven-plugin</artifactId>
+            <version>1.6</version>
+            <executions>
+              <execution>
+                <goals>
+                  <goal>artifacts</goal>
+                </goals>
+              </execution>
+            </executions>
+            <configuration>
+                <attachChecksums>true</attachChecksums>
+            </configuration>
+          </plugin>
+          <plugin>
+              <groupId>org.apache.maven.plugins</groupId>
+              <artifactId>maven-gpg-plugin</artifactId>
+              <configuration>
+                  <ascDirectory>${project.build.directory}/..</ascDirectory>
+              </configuration>
+          </plugin>
+          <plugin>
+            <groupId>org.apache.maven.plugins</groupId>
+            <artifactId>maven-antrun-plugin</artifactId>
+            <version>1.8</version>
+            <executions>
+              <execution>
+                <phase>deploy</phase>
+                <goals>
+                  <goal>run</goal>
+                </goals>
+                <configuration>
+                  <tasks>
+                    <mkdir dir="${project.build.directory}/assemblies" />
+                    <echo message="Here I am!" />
+                    <copy todir="${project.build.directory}/assemblies">
+                      <fileset dir="${settings.localRepository}/org/apache/tiles/tiles-assembly/${project.version}">
+                        <include name="tiles-assembly-${project.version}-*.zip*" />
+                        <include name="tiles-assembly-${project.version}-*.tar.gz*" />
+                        <exclude name="tiles-assembly-${project.version}-source-release.*" />
+                      </fileset>
+                      <mapper type="glob" from="tiles-assembly-*" to="tiles-*" />
+                    </copy>
+                  </tasks>
+                </configuration>
+              </execution>
+            </executions>
+          </plugin>
+        </plugins>
+      </build>
+    </profile>
+  </profiles>
+
+  <dependencies>
+
+    <!-- Main Tiles packages -->
+    <dependency>
+      <groupId>org.apache.tiles</groupId>
+      <artifactId>tiles-api</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.tiles</groupId>
+      <artifactId>tiles-core</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.tiles</groupId>
+      <artifactId>tiles-servlet</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.tiles</groupId>
+      <artifactId>tiles-jsp</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.tiles</groupId>
+      <artifactId>tiles-compat</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.tiles</groupId>
+      <artifactId>tiles-test</artifactId>
+      <version>${project.version}</version>
+      <type>war</type>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.tiles</groupId>
+      <artifactId>tiles-extras</artifactId>
+      <version>${project.version}</version>
+      <type>jar</type>
+    </dependency>
+
+    <!-- Optional dependencies that will be redistributed -->
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-jdk14</artifactId>
+      <scope>runtime</scope>
+    </dependency>
+
+  </dependencies>
+
+</project>
diff --git a/Java-base/tiles/src/assembly/src/main/assembly/bin.xml b/Java-base/tiles/src/assembly/src/main/assembly/bin.xml
new file mode 100644
index 000000000..5fee0959b
--- /dev/null
+++ b/Java-base/tiles/src/assembly/src/main/assembly/bin.xml
@@ -0,0 +1,68 @@
+<!--
+ 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.
+-->
+<assembly>
+    <id>bin</id>
+    <formats>
+        <format>tar.gz</format>
+        <format>zip</format>
+    </formats>
+    <includeSiteDirectory>false</includeSiteDirectory>
+    <dependencySets>
+        <dependencySet>
+            <outputDirectory>/lib</outputDirectory>
+            <outputFileNameMapping>${artifact.artifactId}-${artifact.version}${dashClassifier?}.${artifact.extension}</outputFileNameMapping>
+            <includes>
+                <include>org.slf4j:slf4j-api</include>
+                <include>org.slf4j:jcl-over-slf4j</include>
+                <include>commons-beanutils:commons-beanutils</include>
+                <include>commons-digester:commons-digester</include>
+            </includes>
+        </dependencySet>
+        <dependencySet>
+            <outputDirectory>/lib/optional</outputDirectory>
+            <outputFileNameMapping>${artifact.artifactId}-${artifact.version}${dashClassifier?}.${artifact.extension}</outputFileNameMapping>
+            <excludes>
+                <exclude>org.apache.tiles:*</exclude>
+                <exclude>org.slf4j:slf4j-api</exclude>
+                <exclude>org.slf4j:jcl-over-slf4j</exclude>
+                <exclude>commons-beanutils:commons-beanutils</exclude>
+                <exclude>commons-digester:commons-digester</exclude>
+            </excludes>
+        </dependencySet>
+        <dependencySet>
+            <outputDirectory>/</outputDirectory>
+            <outputFileNameMapping>${artifact.artifactId}-${artifact.version}${dashClassifier?}.${artifact.extension}</outputFileNameMapping>
+            <includes>
+                <include>org.apache.tiles:*</include>
+            </includes>
+            <excludes>
+                <exclude>org.apache.tiles:tiles-test</exclude>
+            </excludes>
+        </dependencySet>
+    </dependencySets>
+
+    <fileSets>
+        <fileSet>
+            <directory>..</directory>
+            <outputDirectory>/</outputDirectory>
+            <includes>
+                <include>*LICENSE.*</include>
+                <include>NOTICE.txt</include>
+            </includes>
+        </fileSet>
+    </fileSets>
+</assembly>
diff --git a/Java-base/tiles/src/assembly/src/main/assembly/docs.xml b/Java-base/tiles/src/assembly/src/main/assembly/docs.xml
new file mode 100644
index 000000000..72fae5544
--- /dev/null
+++ b/Java-base/tiles/src/assembly/src/main/assembly/docs.xml
@@ -0,0 +1,49 @@
+<!--
+ 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.
+-->
+<assembly>
+    <id>docs</id>
+    <formats>
+        <format>tar.gz</format>
+        <format>zip</format>
+    </formats>
+    <includeSiteDirectory>false</includeSiteDirectory>
+    <dependencySets>
+    </dependencySets>
+
+    <fileSets>
+        <fileSet>
+            <directory>..</directory>
+            <outputDirectory>/</outputDirectory>
+            <includes>
+                <include>LICENSE.txt</include>
+                <include>NOTICE.txt</include>
+            </includes>
+        </fileSet>
+        <fileSet>
+            <directory>../target/site/apidocs</directory>
+            <outputDirectory>apidocs</outputDirectory>
+        </fileSet>
+        <fileSet>
+            <directory>../tiles-core/target/site/dtddoc</directory>
+            <outputDirectory>dtddoc</outputDirectory>
+        </fileSet>
+        <fileSet>
+            <directory>../tiles-jsp/target/site/tlddoc</directory>
+            <outputDirectory>tlddoc</outputDirectory>
+        </fileSet>
+    </fileSets>
+</assembly>
diff --git a/Java-base/tiles/src/assembly/src/main/assembly/src.xml b/Java-base/tiles/src/assembly/src/main/assembly/src.xml
new file mode 100644
index 000000000..79c9b4c87
--- /dev/null
+++ b/Java-base/tiles/src/assembly/src/main/assembly/src.xml
@@ -0,0 +1,153 @@
+<!--
+ 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.
+-->
+<assembly>
+    <id>src</id>
+    <formats>
+        <format>tar.gz</format>
+        <format>zip</format>
+    </formats>
+    <fileSets>
+        <fileSet>
+            <directory>../</directory>
+            <outputDirectory>src/</outputDirectory>
+            <includes>
+                <include>pom.xml</include>
+                <include>src/</include>
+            </includes>
+        </fileSet>
+        <fileSet>
+            <directory>../</directory>
+            <outputDirectory>/</outputDirectory>
+            <includes>
+                <include>LICENSE.txt</include>
+                <include>NOTICE.txt</include>
+            </includes>
+        </fileSet>
+        <fileSet>
+            <directory>../tiles-core</directory>
+            <outputDirectory>src/tiles-core</outputDirectory>
+            <includes>
+                <include>pom.xml</include>
+                <include>src/</include>
+            </includes>
+        </fileSet>
+        <fileSet>
+            <directory>../tiles-api</directory>
+            <outputDirectory>src/tiles-api</outputDirectory>
+            <includes>
+                <include>pom.xml</include>
+                <include>src/</include>
+            </includes>
+        </fileSet>
+        <fileSet>
+            <directory>../tiles-servlet</directory>
+            <outputDirectory>src/tiles-servlet</outputDirectory>
+            <includes>
+                <include>pom.xml</include>
+                <include>src/</include>
+            </includes>
+        </fileSet>
+        <fileSet>
+            <directory>../tiles-jsp</directory>
+            <outputDirectory>src/tiles-jsp</outputDirectory>
+            <includes>
+                <include>pom.xml</include>
+                <include>src/</include>
+            </includes>
+        </fileSet>
+        <fileSet>
+            <directory>../tiles-el</directory>
+            <outputDirectory>src/tiles-el</outputDirectory>
+            <includes>
+                <include>pom.xml</include>
+                <include>src/</include>
+            </includes>
+        </fileSet>
+        <fileSet>
+            <directory>../tiles-mvel</directory>
+            <outputDirectory>src/tiles-mvel</outputDirectory>
+            <includes>
+                <include>pom.xml</include>
+                <include>src/</include>
+            </includes>
+        </fileSet>
+        <fileSet>
+            <directory>../tiles-ognl</directory>
+            <outputDirectory>src/tiles-ognl</outputDirectory>
+            <includes>
+                <include>pom.xml</include>
+                <include>src/</include>
+            </includes>
+        </fileSet>
+        <fileSet>
+            <directory>../tiles-template</directory>
+            <outputDirectory>src/tiles-template</outputDirectory>
+            <includes>
+                <include>pom.xml</include>
+                <include>src/</include>
+            </includes>
+        </fileSet>
+        <fileSet>
+            <directory>../tiles-freemarker</directory>
+            <outputDirectory>src/tiles-freemarker</outputDirectory>
+            <includes>
+                <include>pom.xml</include>
+                <include>src/</include>
+            </includes>
+        </fileSet>
+        <fileSet>
+            <directory>../tiles-velocity</directory>
+            <outputDirectory>src/tiles-velocity</outputDirectory>
+            <includes>
+                <include>pom.xml</include>
+                <include>src/</include>
+            </includes>
+        </fileSet>
+        <fileSet>
+            <directory>../tiles-extras</directory>
+            <outputDirectory>src/tiles-extras</outputDirectory>
+            <includes>
+                <include>pom.xml</include>
+                <include>src/</include>
+            </includes>
+        </fileSet>
+        <fileSet>
+            <directory>../tiles-compat</directory>
+            <outputDirectory>src/tiles-compat</outputDirectory>
+            <includes>
+                <include>pom.xml</include>
+                <include>src/</include>
+            </includes>
+        </fileSet>
+        <fileSet>
+            <directory>../tiles-test</directory>
+            <outputDirectory>src/tiles-test</outputDirectory>
+            <includes>
+                <include>pom.xml</include>
+                <include>src/</include>
+            </includes>
+        </fileSet>
+        <fileSet>
+            <directory>../assembly</directory>
+            <outputDirectory>src/assembly</outputDirectory>
+            <includes>
+                <include>pom.xml</include>
+                <include>src/</include>
+            </includes>
+        </fileSet>
+    </fileSets>
+</assembly>
diff --git a/Java-base/tiles/src/assembly/src/main/resources/LICENSE.txt b/Java-base/tiles/src/assembly/src/main/resources/LICENSE.txt
new file mode 100644
index 000000000..d64569567
--- /dev/null
+++ b/Java-base/tiles/src/assembly/src/main/resources/LICENSE.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/Java-base/tiles/src/assembly/src/main/resources/NOTICE.txt b/Java-base/tiles/src/assembly/src/main/resources/NOTICE.txt
new file mode 100644
index 000000000..1f13ff856
--- /dev/null
+++ b/Java-base/tiles/src/assembly/src/main/resources/NOTICE.txt
@@ -0,0 +1,6 @@
+   Apache Tiles
+   Copyright 1999-2009 The Apache Software Foundation
+
+   This product includes software developed at
+   The Apache Software Foundation (http://www.apache.org/).
+
diff --git a/Java-base/tiles/src/assembly/src/site/site.xml b/Java-base/tiles/src/assembly/src/site/site.xml
new file mode 100644
index 000000000..de31de869
--- /dev/null
+++ b/Java-base/tiles/src/assembly/src/site/site.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<project name="Apache Tiles - Assembly">
+     <skin>
+        <groupId>org.apache.maven.skins</groupId>
+        <artifactId>maven-fluido-skin</artifactId>
+        <version>1.3.0</version>
+     </skin>
+     <custom>
+        <fluidoSkin>
+        <topBarEnabled>true</topBarEnabled>
+        <sideBarEnabled>false</sideBarEnabled>
+        <searchEnabled>true</searchEnabled>
+        <gitHub>
+            <projectId>apache/tiles</projectId>
+            <ribbonOrientation>right</ribbonOrientation>
+            <ribbonColor>darkblue</ribbonColor>
+        </gitHub>
+        </fluidoSkin>
+     </custom>
+    <bannerLeft>
+        <name>Apache Tiles&#8482;</name>
+        <src>http://tiles.apache.org/images/logo.png</src>
+        <href>http://tiles.apache.org</href>
+    </bannerLeft>
+    <bannerRight>
+        <name>Apache Software Foundation</name>
+        <src>http://struts.apache.org/images/asf-logo.gif</src>
+        <href>http://www.apache.org</href>
+    </bannerRight>
+    <body>
+
+        <menu name="Apache Tiles&#8482;">
+            <item
+                   name="Welcome"
+                   href="../../index.html"/>
+            <item
+                    name="Tiles 3.0.x"
+                    href="../../framework/index.html"/>
+            <item
+                    name="Autotag 1.0.x"
+                    href="../../tiles-autotag/index.html"/>
+            <item
+                    name="Request 1.0.x"
+                    href="../../tiles-request/index.html"/>
+            <item
+                   name="Security bulletins"
+                   href="../security/index.html"/>
+            <item
+                   name="Download"
+                   href="http://tiles.apache.org/download.html"/>
+        </menu>
+
+        ${modules}
+        ${reports}
+
+
+        <footer>
+            <div class="row span12">
+                Apache Tiles, Tiles, Apache, the Apache feather logo, and the Apache Tiles
+                project logos are trademarks of The Apache Software Foundation.
+            </div>
+        </footer>
+    </body>
+</project>
diff --git a/Java-base/tiles/src/pom.xml b/Java-base/tiles/src/pom.xml
new file mode 100644
index 000000000..f023ddc35
--- /dev/null
+++ b/Java-base/tiles/src/pom.xml
@@ -0,0 +1,393 @@
+<?xml version="1.0"?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <parent>
+        <artifactId>tiles-master</artifactId>
+        <groupId>org.apache.tiles</groupId>
+        <version>7</version>
+        <relativePath />
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.apache.tiles</groupId>
+    <artifactId>tiles-parent</artifactId>
+    <version>3.1-SNAPSHOT</version>
+    <packaging>pom</packaging>
+    <name>Tiles 3</name>
+    <description>Tiles 3: A framework for page composition.</description>
+    <url>http://tiles.apache.org/framework/</url>
+    <scm>
+        <connection>scm:svn:http://svn.apache.org/repos/asf/tiles/framework/trunk/</connection>
+        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/tiles/framework/trunk/</developerConnection>
+        <url>http://svn.apache.org/viewvc/tiles/framework/trunk/</url>
+    </scm>
+
+    <ciManagement />
+
+    <modules>
+        <module>tiles-api</module>
+        <module>tiles-core</module>
+        <module>tiles-template</module>
+        <module>tiles-servlet</module>
+        <module>tiles-jsp</module>
+        <module>tiles-freemarker</module>
+        <module>tiles-velocity</module>
+        <module>tiles-el</module>
+        <module>tiles-mvel</module>
+        <module>tiles-ognl</module>
+        <module>tiles-compat</module>
+        <module>tiles-extras</module>
+        <module>assembly</module>
+        <module>tiles-test-pom</module>
+    </modules>
+
+    <issueManagement>
+        <system>JIRA</system>
+        <url>https://issues.apache.org/jira/browse/TILES</url>
+        <!-- dev@tiles.apache.org :: this line satisfies INFRA-3329 -->
+    </issueManagement>
+
+    <distributionManagement>
+        <site>
+            <id>apache-site</id>
+            <url>scp://people.apache.org/www/tiles.apache.org/framework</url>
+        </site>
+    </distributionManagement>
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.apache.tiles</groupId>
+                <artifactId>tiles-api</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.tiles</groupId>
+                <artifactId>tiles-core</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.tiles</groupId>
+                <artifactId>tiles-servlet</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.tiles</groupId>
+                <artifactId>tiles-template</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+
+            <dependency>
+                <groupId>org.apache.velocity</groupId>
+                <artifactId>velocity-tools</artifactId>
+                <version>2.0</version>
+                <exclusions>
+                    <exclusion>
+                        <artifactId>struts-taglib</artifactId>
+                        <groupId>org.apache.struts</groupId>
+                    </exclusion>
+                    <exclusion>
+                        <artifactId>struts-tiles</artifactId>
+                        <groupId>org.apache.struts</groupId>
+                    </exclusion>
+                    <exclusion>
+                        <artifactId>struts-core</artifactId>
+                        <groupId>org.apache.struts</groupId>
+                    </exclusion>
+                    <exclusion>
+                        <groupId>commons-logging</groupId>
+                        <artifactId>commons-logging</artifactId>
+                    </exclusion>
+                    <exclusion>
+                        <artifactId>sslext</artifactId>
+                        <groupId>sslext</groupId>
+                    </exclusion>
+                    <exclusion>
+                        <artifactId>commons-chain</artifactId>
+                        <groupId>commons-chain</groupId>
+                    </exclusion>
+                    <exclusion>
+                        <artifactId>commons-validator</artifactId>
+                        <groupId>commons-validator</groupId>
+                    </exclusion>
+                    <exclusion>
+                        <artifactId>commons-digester</artifactId>
+                        <groupId>commons-digester</groupId>
+                    </exclusion>
+                    <exclusion>
+                        <artifactId>commons-beanutils</artifactId>
+                        <groupId>commons-beanutils</groupId>
+                    </exclusion>
+                    <exclusion>
+                        <artifactId>dom4j</artifactId>
+                        <groupId>dom4j</groupId>
+                    </exclusion>
+                </exclusions>
+            </dependency>
+
+            <dependency>
+                <groupId>commons-digester</groupId>
+                <artifactId>commons-digester</artifactId>
+                <version>2.0</version>
+                <exclusions>
+                    <exclusion>
+                        <groupId>commons-logging</groupId>
+                        <artifactId>commons-logging</artifactId>
+                    </exclusion>
+                </exclusions>
+            </dependency>
+            <dependency>
+                <groupId>org.freemarker</groupId>
+                <artifactId>freemarker</artifactId>
+                <version>2.3.15</version>
+            </dependency>
+
+            <dependency>
+                <groupId>ognl</groupId>
+                <artifactId>ognl</artifactId>
+                <version>2.7.3</version>
+            </dependency>
+            <dependency>
+                <groupId>org.mvel</groupId>
+                <artifactId>mvel2</artifactId>
+                <version>2.3.2.Final</version>
+            </dependency>
+            <dependency>
+                <groupId>javax.servlet</groupId>
+                <artifactId>servlet-api</artifactId>
+                <version>2.5</version>
+                <scope>provided</scope>
+            </dependency>
+            <dependency>
+                <groupId>javax.servlet.jsp</groupId>
+                <artifactId>jsp-api</artifactId>
+                <version>2.1</version>
+                <scope>provided</scope>
+            </dependency>
+            <dependency>
+                <groupId>javax.el</groupId>
+                <artifactId>el-api</artifactId>
+                <version>1.0</version>
+                <scope>provided</scope>
+            </dependency>
+            <dependency>
+                <groupId>junit</groupId>
+                <artifactId>junit</artifactId>
+                <version>4.7</version>
+                <scope>test</scope>
+            </dependency>
+            <dependency>
+                <groupId>org.easymock</groupId>
+                <artifactId>easymock</artifactId>
+                <version>3.0</version>
+                <scope>test</scope>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.shale</groupId>
+                <artifactId>shale-test</artifactId>
+                <version>1.0.5</version>
+                <scope>test</scope>
+            </dependency>
+            <dependency>
+                <groupId>org.easymock</groupId>
+                <artifactId>easymockclassextension</artifactId>
+                <version>3.0</version>
+                <scope>test</scope>
+            </dependency>
+            <dependency>
+            	<groupId>org.slf4j</groupId>
+            	<artifactId>slf4j-api</artifactId>
+            	<version>1.7.6</version>
+            </dependency>
+            <dependency>
+            	<groupId>org.slf4j</groupId>
+            	<artifactId>slf4j-jdk14</artifactId>
+            	<version>1.7.6</version>
+                <scope>test</scope>
+            </dependency>
+            <dependency>
+                <groupId>org.slf4j</groupId>
+                <artifactId>jcl-over-slf4j</artifactId>
+                <version>1.7.6</version>
+                <scope>test</scope>
+            </dependency>
+            <dependency>
+            	<groupId>org.apache.tiles</groupId>
+            	<artifactId>tiles-request-api</artifactId>
+            	<version>${tiles.request.version}</version>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+
+    <build>
+        <pluginManagement>
+            <plugins>
+                <plugin>
+                    <artifactId>maven-jar-plugin</artifactId>
+                    <configuration>
+                        <archive>
+                            <manifestFile>${tiles.manifestfile}</manifestFile>
+                            <manifest>
+                                <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
+                                <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+                            </manifest>
+                        </archive>
+                    </configuration>
+                </plugin>
+                <plugin>
+                    <groupId>org.apache.felix</groupId>
+                    <artifactId>maven-bundle-plugin</artifactId>
+                    <version>2.3.7</version>
+                    <inherited>true</inherited>
+                </plugin>
+            </plugins>
+        </pluginManagement>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <configuration>
+                    <excludeDependencies>true</excludeDependencies>
+                    <manifestLocation>target/osgi</manifestLocation>
+                    <instructions>
+                        <_nouses>true</_nouses>
+                        <Bundle-SymbolicName>${tiles.osgi.symbolicName}</Bundle-SymbolicName>
+                        <Export-Package>${tiles.osgi.export}</Export-Package>
+                        <Private-Package>${tiles.osgi.private}</Private-Package>
+                        <Import-Package>${tiles.osgi.import}</Import-Package>
+                        <DynamicImport-Package>${tiles.osgi.dynamicImport}</DynamicImport-Package>
+                        <Bundle-DocURL>${project.url}</Bundle-DocURL>
+                        <Specification-Title>${project.name}</Specification-Title>
+                        <Specification-Version>${project.version}</Specification-Version>
+                        <Specification-Vendor>${project.organization.name}</Specification-Vendor>
+                        <Implementation-Title>${project.name}</Implementation-Title>
+                        <Implementation-Version>${project.version}</Implementation-Version>
+                        <Implementation-Vendor>${project.organization.name}</Implementation-Vendor>
+                        <Implementation-Vendor-Id>org.apache</Implementation-Vendor-Id>
+                    </instructions>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>bundle-manifest</id>
+                        <phase>process-classes</phase>
+                        <goals>
+                            <goal>manifest</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-release-plugin</artifactId>
+                <configuration>
+                    <releaseProfiles>apache-release</releaseProfiles><!-- xxx tiles still uses "release" instead of "apache-release" -->
+                    <goals>deploy site-deploy</goals>
+                </configuration>
+            </plugin>
+        </plugins>
+
+        <defaultGoal>install</defaultGoal>
+    </build>
+
+    <properties>
+        <maven.javadoc.failOnError>false</maven.javadoc.failOnError> <!-- remove with master-8 -->
+        <tiles.osgi.symbolicName>org.apache.${project.artifactId}</tiles.osgi.symbolicName>
+        <tiles.osgi.export>org.apache.tiles.*;version=${project.version}</tiles.osgi.export>
+        <tiles.osgi.import>*</tiles.osgi.import>
+        <tiles.osgi.dynamicImport />
+        <tiles.osgi.private />
+        <tiles.manifestfile>target/osgi/MANIFEST.MF</tiles.manifestfile>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <tiles.request.version>1.0.7</tiles.request.version>
+        <tiles.autotag.version>1.1.0</tiles.autotag.version>
+    </properties>
+
+    <dependencies />
+
+    <profiles>
+        <profile>
+            <id>apache-release</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <artifactId>maven-install-plugin</artifactId>
+                        <configuration>
+                            <createChecksum>true</createChecksum>
+                        </configuration>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>rat-maven-plugin</artifactId>
+                        <version>1.0-alpha-3</version>
+                        <executions>
+                            <execution>
+                                <phase>verify</phase>
+                                <goals>
+                                    <goal>check</goal>
+                                </goals>
+                                <configuration>
+                                    <addDefaultLicenseMatchers>false</addDefaultLicenseMatchers>
+                                    <licenseMatchers>
+                                        <classNames>
+                                            <className>rat.analysis.license.ApacheSoftwareLicense20</className>
+                                        </classNames>
+                                    </licenseMatchers>
+                                    <includes>
+                                        <include>pom.xml</include>
+                                        <include>src/**</include>
+                                    </includes>
+                                    <excludes>
+                                        <exclude>**/*LICENSE.txt</exclude>
+                                        <exclude>**/*MANIFEST.MF</exclude>
+                                    </excludes>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+        <profile>
+            <id>linkcheck</id>
+            <reporting>
+                <plugins>
+                    <plugin>
+                        <artifactId>maven-linkcheck-plugin</artifactId>
+                        <version>1.1</version>
+                        <configuration>
+                            <excludedLinks>
+                                <excludedLink>/*</excludedLink>
+                                <excludedLink>**/index.html</excludedLink>
+                                <excludedLink>**/logo.png</excludedLink>
+                                <excludedLink>**/tiles-jsp/tagreference.html</excludedLink>
+                            </excludedLinks>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </reporting>
+        </profile>
+
+    </profiles>
+
+</project>
diff --git a/Java-base/tiles/src/src/site/apt/config-reference.apt b/Java-base/tiles/src/src/site/apt/config-reference.apt
new file mode 100644
index 000000000..71a7b6dce
--- /dev/null
+++ b/Java-base/tiles/src/src/site/apt/config-reference.apt
@@ -0,0 +1,250 @@
+~~ $Id$
+~~
+~~ 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.
+~~
+         -----------
+         Tiles Configuration Reference
+         -----------
+
+Configuring Tiles
+
+  Configuring Tiles means creating the following objects:
+  * an instance of org.apache.tiles.request.ApplicationContext,
+  * an instance of org.apache.tiles.TilesContainer.
+  Usually these are created by an instance of org.apache.tiles.startup.TilesInitializer.
+
+  Several MVC frameworks (struts, spring, shale) provide an easy integration with tiles.
+
+* Starting Tiles in a web application
+
+  Tiles has always been a web application package, usually used in conjunction
+  with Struts. Apache Tiles\u0099 evolved to the point of being technology-independent, but
+  its use in a Servlet-based web application will be the most frequent use case.
+
+  To start Tiles you can extend
+  {{{./apidocs/org/apache/tiles/web/startup/AbstractTilesListener.html}AbstractTilesListener}}
+  and implement the <<<createTilesInitializer>>> method:
+
+--------------------------
+protected TilesInitializer createTilesInitializer() {
+    return new MyCustomTilesInitializer();
+}
+--------------------------
+
+  You can use {{{./apidocs/org/apache/tiles/startup/AbstractTilesInitializer.html}AbstractTilesInitializer}}
+  as a basis.
+
+  Then you can start Tiles by specifing it in your <<<web.xml>>> file:
+
+-------------------------------
+<listener>
+    <listener-class>my.package.MyTilesListener</listener-class>
+</listener>
+-------------------------------
+
+* Starting Tiles in a portlet application
+
+  TBD
+
+{Ready-made configuration classes}
+
+  There are some classes that allows to play with Tiles without writing custom code.
+
+* Simple configuration
+
+  {{{./apidocs/org/apache/tiles/web/startup/simple/SimpleTilesListener.html}SimpleTilesListener}}
+  or
+  {{{./apidocs/org/apache/tiles/startup/DefaultTilesInitializer.html}DefaultTilesInitializer}}
+  are the "simple" way to load Tiles. This was the default for Tiles 2.1 and prior versions.
+
+  This configuration has the following characteristics:
+
+  * loads the "/WEB-INF/tiles.xml" file;
+
+  * allows support for JSP, Servlets and Portlets;
+
+  * no expression language is allowed;
+
+  * wildcard expressions can be used to declare definition names.
+
+* Feature-Complete configuration
+
+  It is possible to startup Tiles turning all the new features on by using
+  {{{./apidocs/org/apache/tiles/extras/complete/CompleteAutoloadTilesListener.html}CompleteAutoloadTilesListener}}
+  or
+  {{{./apidocs/org/apache/tiles/extras/complete/CompleteAutoloadTilesInitializer.html}CompleteAutoloadTilesInitializer}}
+  available in the <<<tiles-extras>>> module. This initializer turns on:
+
+  * {{{./tutorial/integration/freemarker.html}Freemarker}} and {{{./tutorial/integration/velocity.html}Velocity}} support;
+
+  * using EL, OGNL and MVEL as {{{./tutorial/advanced/el-support.html}evaluation languages}};
+
+  * using Wildcards and Regular expression as {{{./tutorial/advanced/wildcard.html}pattern matching languages}};
+
+  * loading {{{./migration/configuration.html#Reusing_old_Tiles_configuration_files}Tiles 1.x definition files}};
+
+  * loads all the files named "tiles*.xml" under /WEB-INF and under every META-INF in any part of the classpath.
+
+  * using a mutable container to create Definitions at runtime.
+
+* Modular initialization
+
+  It is possible to startup Tiles in a <<modular>> way, that is loading
+  modules of independent Tiles configuration.
+
+  To turn it on, you need to use
+  {{{./apidocs/org/apache/tiles/extras/module/ModularTilesListener.html}ModularTilesListener}}
+  or
+  {{{./apidocs/org/apache/tiles/extras/module/ModularTilesInitializer.html}ModularTilesInitializer}}
+  available in the <<<tiles-extras>>> module.
+
+  Add in your manifest file, under the <<<META-INF/MANIFEST.MF>>>
+  path, the <<<Tiles-Initializer>>> property, whose value is the name of the class of the
+  needed initializer. For example:
+
+---------------------------
+Manifest-Version: 1.0
+Tiles-Initializer: org.apache.tiles.extras.module.ModularTilesInitializerTest$TilesInitializer1
+---------------------------
+
+  Every initializer that is found will be loaded and "initialized", and destroyed when the
+  main initializer is destroyed.
+
+Configuring Tiles internals
+
+  The container and the application context must be configured to allow custom behaviour
+  and to load definitions from various sources.
+
+* Custom {ApplicationContext}
+
+  Custom ApplicationContext can be provided by implementing
+  {{{/tiles-request/apidocs/org/apache/tiles/request/ApplicationContext.html}ApplicationContext}}.
+  If you are under a servlet environment, you can override
+  {{{/tiles-request/apidocs/org/apache/tiles/request/servlet/ServletApplicationContext.html}ServletApplicationContext}}.
+
+  To use it, you need to override the
+  {{{./apidocs/org/apache/tiles/startup/AbstractTilesInitializer.html#method_summary}createTilesApplicationContext}}
+  method of AbstractTilesInitializer.
+
+  The reason to use a custom Tiles application context could be:
+
+  * supporting a platform not supported yet;
+
+  * providing custom behaviour, such as loading resources in a different manner.
+
+* Custom {TilesContainerFactory}
+
+  Custom Tiles containers can be created by custom Tiles container factories.
+  You have to create a class that extends
+  {{{./apidocs/org/apache/tiles/factory/AbstractTilesContainerFactory.html}AbstractTilesContainerFactory}}.
+  In particular you can use {{{./apidocs/org/apache/tiles/factory/BasicTilesContainerFactory.html}BasicTilesContainerFactory}}
+  as a basis for your extended configuration. <<<BasicTilesContainerFactory>>>
+  is the configuration that replicates the default configuration of Tiles,
+  i.e. the one that assumes when no additional parameter is provided.
+  The
+  {{{./apidocs/org/apache/tiles/factory/BasicTilesContainerFactory.html}Javadoc documentation of BasicTilesContainerFactory}}
+  documents all the methods that can be overridden to use your own
+  configuration.
+  
+** Changing the path for the Tiles Definitions file
+
+  The <<<BasicTilesContainerFactory>>> loads the "/WEB-INF/tiles.xml" file; the <<<CompleteAutoloadTilesContainerFactory>>>
+  loads all the files named "tiles*.xml" under /WEB-INF and under every META-INF in any part of the classpath.
+  
+  If this behaviour doesn't suits you, you can override the method <<<getSources>>> and retrieve whatever resource you
+  prefer. Just specify the path for the default locale; Tiles will extrapolate and load the localized files as needed.
+
+* Custom components
+
+  These components can be used by overriding the appropriate <<<create>>> method in a custom TilesContainerFactory.
+  
+** Custom {LocaleResolver}
+  
+  The default implementation is {{{./apidocs/org/apache/tiles/locale/impl/DefaultLocaleResolver.html}DefaultLocaleResolver}}.
+
+** Custom {DefinitionDAO}
+
+  The default implementation is {{{./apidocs/org/apache/tiles/definition/dao/ResolvingLocaleUrlDefinitionDAO.html}ResolvingLocaleUrlDefinitionDAO}}.
+  
+** Custom {AttributeEvaluatorFactory}
+
+  The default implementation is {{{./apidocs/org/apache/tiles/evaluator/BasicAttributeEvaluatorFactory.html}BasicAttributeEvaluatorFactory}}.
+  
+  It can be used with a number of AttributeEvaluators like:
+  
+  * the {{{./apidocs/org/apache/tiles/evaluator/impl/DirectAttributeEvaluator.html}DirectAttributeEvaluator}},
+
+  * the {{{./apidocs/org/apache/tiles/el/ELAttributeEvaluator.html}ELAttributeEvaluator}},
+
+  * the {{{./apidocs/org/apache/tiles/mvel/MVELAttributeEvaluator.html}MVELAttributeEvaluator}},
+
+  * the {{{./apidocs/org/apache/tiles/ognl/OGNLAttributeEvaluator.html}OGNLAttributeEvaluator}}.
+  
+  Please see {{{./xref/org/apache/tiles/extras/complete/CompleteAutoloadTilesContainerFactory.html}CompleteAutoloadTilesContainerFactory}}
+  for an example of how to configure those.
+
+** Custom {PreparerFactory}
+
+  The default implementation is {{{./apidocs/org/apache/tiles/preparer/factory/BasicPreparerFactory.html}BasicPreparerFactory}}.
+
+  Currently the preparer is associated to a definition using its class name.
+  There will be only <<one>> instance per unique class name. If you want to
+  customize this behaviour, you have to create your own implementation of the
+  <<<PreparerFactory>>> interface.
+
+  For example, the {{{./tutorial/integration/frameworks.html}Struts 1 - Apache Tiles\u0099 integration}}
+  defines a <<<PreparerFactory>>> that can use a URL as a preparer.
+
+** Custom {PatternDefinitionResolver}
+
+  The default implementation is {{{./apidocs/org/apache/tiles/definition/pattern/BasicPatternDefinitionResolver.html}BasicPatternDefinitionResolver}},
+  that implements the <wildcard> syntax.
+  
+  <<<CompleteAutoloadTilesContainerFactory>>> defines a <<<PrefixedPatternDefinitionResolver>>> to enable the use of 
+  both the <wildcard> syntax and the <regexp> syntax, with appropriate prefixes.
+
+* Registering {Renderers}
+
+  Custom {{{/tiles-request/apidocs/org/apache/tiles/request/render/Renderer.html}Renderers}} can be registered by overriding the methods
+  <<<registerAttributeRenderers>>> and <<<createDefaultAttributeRenderer>>>.
+  
+  <<<BasicTilesContainerFactory>>> registers 3 renderers: <<<string>>>, <<<template>>>, and <<<definition>>>, in order to
+  render plain strings, JSPs and tiles definitions.
+  
+  <<<CompleteAutoloadTilesContainerFactory>>> registers 5 renderers: <<<string>>>, <<<template>>>, <<<freemarker>>>, 
+  <<<velocity>>> and <<<definition>>>, in order to render plain strings, JSPs, freemarker and velocity templates 
+  and tiles definitions.
+
+* Changing the {definition files}
+
+  The default implementation <<<BasicTilesContainerFactory>>> loads the file named <<</WEB-INF/tiles.xml>>>.
+
+  <<<CompleteAutoloadTilesContainerFactory>>> loads all files named <<</WEB-INF/tiles*.xml>>> in the web application, or <<</META-INF/tiles*.xml>>> on the classpath.
+
+  Those file names can be changed by overriding the method <<<getSources>>>:
+
+-----------
+protected List<ApplicationResource> getSources(ApplicationContext applicationContext) {
+    return applicationContext.getResources("/WEB-INF/my-tiles-definitions-file.xml");
+}
+-----------
+
+  Please note that when using <<<CompleteAutoloadTilesContainerFactory>>>,
+  the <<<ApplicationContext>>> loads the resources via spring, and supports 
+  {{{http://static.springsource.org/spring/docs/2.5.x/reference/resources.html#resources-resource-strings}the spring syntax}} for locating resources.
+
diff --git a/Java-base/tiles/src/src/site/apt/dev/release.apt b/Java-base/tiles/src/src/site/apt/dev/release.apt
new file mode 100644
index 000000000..5c5341a0c
--- /dev/null
+++ b/Java-base/tiles/src/src/site/apt/dev/release.apt
@@ -0,0 +1,327 @@
+~~ $Id$
+~~
+~~ 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.
+~~
+         -----------
+         Release Process
+         -----------
+
+Tiles Release Process
+
+  Here you will find the steps to create releases for Tiles.
+
+Prerequisites
+
+  To create a release you have to install:
+
+  * {{{http://www.oracle.com/technetwork/java/javase/overview/index.html}Java 9}}. If you are using a newer
+  version of Java <<change JAVA_HOME environment variable>>
+  when calling Maven, so it points to an instance of Java 9;
+
+  * {{{http://maven.apache.org/}Maven 3.2.2+}};
+
+  * {{{http://www.gnupg.org/}GnuPG}};
+
+  * {{{http://www.openssh.com/}OpenSSH}};
+
+  * {{{http://www.graphviz.org/}GraphViz}};
+
+One-time operations
+
+  These operations need to be performed only one time.
+
+* Create and publish your GPG key
+
+  To create a GPG key, follow the
+  {{{http://www.apache.org/dev/openpgp.html}guidelines}}.
+  Include it in:
+
+-------------------------------------
+https://svn.apache.org/repos/asf/tiles/site/KEYS
+-------------------------------------
+
+  Publish your GPG key in a PGP key server, such as
+  {{{http://pgp.mit.edu/} MIT Keyserver}}.
+
+* Modify <<<settings.xml>>>
+
+  Your <<<settings.xml>>> must be modified to allow deployment.
+
+  This is the minimal configuration, obviously if you already have a <<<settings.xml>>> file,
+  you must edit it:
+
+---------------------------
+<settings xmlns="http://maven.apache.org/POM/4.0.0"
+      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
+                      http://maven.apache.org/xsd/settings-1.0.0.xsd">
+    <servers>
+        <server>
+            <id>apache-site</id>
+            <username>YOUR_APACHE_USERNAME</username>
+            <filePermissions>664</filePermissions>
+            <directoryPermissions>775</directoryPermissions>
+        </server>
+        <server>
+            <id>apache.snapshots.https</id>
+            <username>YOUR_APACHE_USERNAME</username>
+            <password>YOUR_APACHE_PASSWORD</password>
+        </server>
+        <server>
+            <id>apache.releases.https</id>
+            <username>YOUR_APACHE_USERNAME</username>
+            <password>YOUR_APACHE_PASSWORD</password>
+        </server>
+    </servers>
+    <profiles>
+        <profile>
+            <id>release</id>
+            <properties>
+                <gpg.passphrase>YOUR_SECRET_PHRASE</gpg.passphrase>
+            </properties>
+            </profile>
+        </profile>
+    </profiles>
+</settings>
+---------------------------
+
+Repeatable operations
+
+  These steps must be performed <<for each>> release.
+
+* Prepare the release tag
+
+  To prepare the release Subversion tag, check out the branch/trunk from where
+  you are preparing the release and type:
+
+-----------------------------------
+mvn release:prepare -Dusername=YOUR_SVN_USER -Dpassword=YOUR_SVN_PASSWORD
+-----------------------------------
+
+  The plugin interactively will ask you the version to release, the Subversion
+  tag to use and the next snapshot version. It is recommended to use the tag:
+  <<tiles-X.X.X>>.
+
+  See also {{{http://www.apache.org/dev/publishing-maven-artifacts.html}the recommendations of the ASF}}.
+
+* Perform the Release
+
+  To perform the release, i.e. creating and deploying Maven artifacts, use:
+
+-----------------------------------
+mvn release:perform -Duser.name=YOUR_PEOPLE_APACHE_SSH_USER -Darguments="-Duser.name=YOUR_PEOPLE_APACHE_SSH_USER"
+-----------------------------------
+
+  It should compile and test everything, build and upload the artifacts and the website for the project.
+
+  Upload the assemblies manually with
+
+-----------------------------------
+cd target/
+svn co https://dist.apache.org/repos/dist/dev/tiles tiles-dist-dev
+mkdir tiles-dist-dev/request/${version}
+cp checkout/assembly/target/assembly/* tiles-dist-dev/${version}/
+svn add tiles-dist-dev/${version}
+svn ci tiles-dist-dev/${version}
+-----------------------------------
+
+* Close the staging repository
+
+  Login to {{{https://repository.apache.org} Nexus repository}} using your Apache LDAP credentials.
+  Click on "Staging". Then click on "tiles" in the list of repositories.
+  In the panel below you should see an open repository that is linked to your username and ip.
+  Right click on this repository and select "Close".
+  This will close the repository from future deployments and make it available for others to view.
+  If you are staging multiple releases together, skip this step until you have staged everything.
+  Enter the name and version of the artifact being released in the "Description" field and then click "Close".
+  This will make it easier to identify it later.
+
+* Verify the staged artifacts
+
+  If you click on your repository, a tree view will appear below.
+  You can then browse the contents to ensure the artifacts are as you expect them.
+  Pay particular attention to the existence of *.asc (signature) files.
+  If the you don't like the content of the repository, right click your repository and choose "Drop".
+  You can then rollback your release and repeat the process.
+
+  Note the repository URL, you will need this in your vote email.
+
+* Verify the uploaded assemblies
+
+  * go to the destination directory on people.apache.org (cd /www/people.apache.org/builds/tiles/${version}).
+
+  * check the presence of the 3 distributions (bin, doc and src), and their signature files (*.asc, *.md5, *sha1).
+
+* Release the JIRA version
+
+  * In JIRA go to the version that you want to release and release it.
+
+  * Create a new version, if it has not been done before.
+
+  * Create the release notes and <<write down the link>> that it uses.
+
+* Send announcement for the test build
+
+  In <<developers mailing list>> send an announcement for the test build:
+
+-----------------------------------
+Subject: [ANNOUNCE] Tiles ${version} test build available
+
+The test build of Tiles ${version} is available.
+
+
+No determination as to the quality ('alpha,' 'beta,' or 'GA') of Tiles
+${version} has been made, and at this time it is simply a "test build". We
+welcome any comments you may have, and will take all feedback into
+account if a quality vote is called for this build.
+
+Release notes:
+
+* ${jira.release.notes}
+
+Distribution:
+
+ * https://dist.apache.org/repos/dist/dev/tiles/${version}/
+
+Maven 2 staging repository:
+
+ * https://repository.apache.org/content/repositories/tiles-[YOUR REPOSITORY ID]/
+
+A vote regarding the quality of this test build will be initiated
+within the next couple of days.
+-----------------------------------
+
+* Call for a vote
+
+  A few days after the test build announcement, call for a vote in
+  <<developers mailing list>>.
+
+-----------------------------------
+Subject: [VOTE] ${version} Release Quality
+
+The Tiles ${version} test build has been available since ${testBuildDate}.
+
+Release notes:
+
+* ${jira.release.notes}
+
+Distribution:
+
+ * https://dist.apache.org/repos/dist/dev/tiles/${version}/
+
+Maven 2 staging repository:
+
+ * https://repository.apache.org/content/repositories/tiles-[YOUR REPOSITORY ID]/
+
+If you have had a chance to review the test build, please respond with
+a vote on its quality:
+
+ [ ] Leave at test build
+ [ ] Alpha
+ [ ] Beta
+ [ ] General Availability (GA)
+
+
+Everyone who has tested the build is invited to vote. Votes by PMC
+members are considered binding. A vote passes if there are at least
+three binding +1s and more +1s than -1s.
+-----------------------------------
+
+* Post-vote operations
+
+  After a vote is finished, and it has been decided that is
+  <<at least of alpha quality>>, there is the need of a post-vote process.
+
+** Promote staged artifacts
+
+  Once the release is deemed fit for public consumption it can be transfered to a production repository where it will be available to all users.
+
+  Login to {{{https://repository.apache.org}Nexus repository}} again.
+  Click on "Staging" and then on the repository with id "tiles-staging".
+  Find your closed staging repository, right click on it and choose "Promote".
+  Select the "Releases" repository and click "Promote".
+
+  Next click on "Repositories", select the "Releases" repository
+  and validate that your artifacts exist as you expect them.
+
+** Move assemblies
+
+  * Move assemblies to the Apache distribution mirrors:
+
+-------------------------------------------
+
+svn mv https://dist.apache.org/repos/dist/dev/tiles/${version} https://dist.apache.org/repos/dist/release/tiles/
+
+-------------------------------------------
+
+** Update the site
+
+  * Wait 24 hours to let the mirror sync to the release and then update the
+  site. In particular you have to update the index and the download pages:
+
+------------------------------------------------
+https://svn.apache.org/repos/asf/tiles/site/src/site/xdoc/index.xml
+https://svn.apache.org/repos/asf/tiles/site/src/site/apt/download.apt
+------------------------------------------------
+
+  Build and publish the site:
+
+--------------------------------------
+mvn site
+mvn site:deploy
+--------------------------------------
+
+** Send announcement
+
+  Finally, send an an announcement to the <<users>> and <<developers mailing
+  list>>:
+
+--------------------------------------
+Subject: [ANNOUNCE] Tiles ${version} ${quality} released
+
+The Apache Tiles team is pleased to announce the release of Tiles ${version}
+${quality}.
+
+Tiles ${version} is available in a binary and a source distribution.
+
+http://tiles.apache.org/download.html
+
+It is also available in the central Maven repository under Group ID
+"org.apache.tiles".
+
+The 3.0.x series of the Apache Tiles framework has a minimum
+requirement of the following specification versions:
+
+* Java Servlet 2.5 and JavaServer Pages (JSP) 2.1
+* Java Standard Edition (Java SE) 1.8
+
+The release notes are available online at:
+
+* ${jira.release.notes}
+
+Please feel free to test the distribution and post your comments to
+the user list, or, if appropriate, file a ticket with JIRA.
+--------------------------------------
+
+** Delete old releases
+
+  As described in http://www.apache.org/dev/release.html#when-to-archive
+
+
+
+  <<You have finished!>>
diff --git a/Java-base/tiles/src/src/site/apt/getting_started.apt b/Java-base/tiles/src/src/site/apt/getting_started.apt
new file mode 100644
index 000000000..b1fba867d
--- /dev/null
+++ b/Java-base/tiles/src/src/site/apt/getting_started.apt
@@ -0,0 +1,84 @@
+~~ $Id$
+~~
+~~ 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.
+~~
+         -----------
+         Getting started
+         -----------
+
+Requirements
+
+  To use Tiles in your application you need:
+
+  * a Java Runtime Environment following the <<Java SE 6.0>> specifications;
+  
+  * implementations for slf4j 1.5.8 (or above) and commons-logging 1.1 (or above);
+
+  * Optionally, depending on which options and templating engines you configure:
+
+    * a servlet container that supports <<Servlet 2.5>> (or above) and <<JSP
+  2.1>> (or above).
+  
+    * a portlet container that supports <<Portlet 2.0>> (or above).
+
+    * check {{{./dependency-management.html}Dependency management}} for a comprehensive list. 
+  
+Installation
+
+  Tiles 3.0 includes a large number of optional jar files and transitive dependencies. We 
+  recommend that you use maven or a compatible dependency manager to retrieve only the files 
+  you really need. 
+
+  If however you wish to install Tiles in your application by hand:
+
+  * {{{/download.html}download}} a distribution of Tiles;
+
+  * if you downloaded the binary distribution, unpack it;
+
+  * copy all the jar files into the classpath of your application (for instance
+  in the <<<WEB-INF/lib>>> directory of your web application). In a web environment, 
+  it is <<not recommended>> to put them in a location where they are shared
+  across the container;
+
+Usage
+
+  If you are using Tiles for the first time, read the
+  {{{./tutorial/index.html}Tutorial}}.
+
+  If you are migrating from Struts-Tiles, see the
+  {{{./migration/index.html}Migration guide}}.
+
+  If you're an advanced user, you may find the details you're looking for in 
+  the {{{./index.html}reference documentation}}.
+
+Examples
+
+  To see Tiles in action, there are two examples:
+
+  * The Tiles test web application, included in <<<examples>>> directory of the
+  binary distribution ({{{/download.html}download it}}).
+
+  * The Tiles showcase, that shows Tiles features and integration with other
+  technologies and frameworks (currently only Struts 1).
+
+  Currently it is still under development, and you can access it through its
+  subversion repository:
+
+-----------------------------
+http://svn.apache.org/repos/asf/tiles/examples/trunk/tiles-showcase/
+-----------------------------
diff --git a/Java-base/tiles/src/src/site/apt/index.apt b/Java-base/tiles/src/src/site/apt/index.apt
new file mode 100644
index 000000000..68323f7e1
--- /dev/null
+++ b/Java-base/tiles/src/src/site/apt/index.apt
@@ -0,0 +1,63 @@
+~~ $Id$
+~~
+~~ 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.
+~~
+         -----------
+         Home
+         -----------
+
+Apache Tiles\u2122
+
+
+    <<{{{http://tiles.apache.org}Apache Tiles}}>> is a template composition
+    framework. Tiles was originally built to simplify the development of web 
+    application user interfaces, but it is no longer restricted to the JavaEE
+    web environment.
+
+    Tiles allows authors to define page fragments which can be assembled
+    into a complete page at runtime.  These fragments, or tiles, can be used
+    as simple includes in order to reduce the duplication of common page
+    elements or embedded within other tiles to develop a series of reusable
+    templates. These templates streamline the development of a consistent
+    look and feel across an entire application.
+
+    {{{/download.html}Download Tiles}}
+
+    {{{./security/index.html}Security bulletins}}
+
+* Documentation
+
+    * {{{./whats-new.html}<<What's new in Tiles 3.0>>}}
+
+    * {{{./tutorial/index.html}Tutorial}}
+
+    * {{{http://cwiki.apache.org/TILES/}Wiki}}
+
+    * Reference
+    
+        ** {{{./getting_started.html}Getting Started}} and installing Tiles
+    
+        ** {{{./config-reference.html}Configuration Reference}}
+
+        ** {{{./apidocs/index.html}Javadocs}}
+
+        ** {{{./tiles-jsp/tlddoc/index.html}Tag library documentation}}
+
+        ** {{{./tiles-core/dtddoc/index.html}Tiles definition file documentation}}
+
+    * {{{./migration/index.html}Migration}} from previous versions
diff --git a/Java-base/tiles/src/src/site/apt/migration/apis.apt b/Java-base/tiles/src/src/site/apt/migration/apis.apt
new file mode 100644
index 000000000..e6572de2f
--- /dev/null
+++ b/Java-base/tiles/src/src/site/apt/migration/apis.apt
@@ -0,0 +1,61 @@
+~~ $Id$
+~~
+~~ 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.
+~~
+         -----------
+         Java APIs considerations
+         -----------
+
+Introduction
+
+  In this part of the migration guide we address the differences of the APIs
+  in Struts Tiles and Apache Tiles\u0099.
+
+  If you are a Tiles extension developer and you want to convert your existing
+  extension, see {{{./extension.html}Tiles extensions}} migration guide.
+
+Controllers and View Preparers
+
+  In Apache Tiles\u0099, the concept of a Tiles <<<Controller>>>, i.e. an object that it is
+  invoked before rendering a definition, has been replaced with
+  <<<ViewPreparer>>>.
+
+  The classes that implement the <<<Controller>>> interface must now implement
+  the new <<<ViewPreparer>>> interface, or extend the <<<ViewPreparerSupport>>>
+  class.
+
+Tiles <<<ComponentContext>>>
+
+  The <<<ComponentContext>>>, i.e. the Tiles-specific context in which the
+  current attribute values are stored, has been renamed to
+  <<<AttributeContext>>>.
+
+  The method <<<getAttribute>>> returns an <<Attribute>>, and not an
+  <<Attribute Value>>, i.e. a simple object.
+
+   * Previous Migration Pages
+
+     ** {{{./index.html}Introduction }}
+
+     ** {{{./configuration.html}Tiles configuration files}}.
+
+     ** {{{./tags.html}Tiles JSP tags}}
+
+   * Next Migration Pages
+
+     ** {{{./extension.html}Tiles extensions}}.
diff --git a/Java-base/tiles/src/src/site/apt/migration/configuration.apt b/Java-base/tiles/src/src/site/apt/migration/configuration.apt
new file mode 100644
index 000000000..4ca41c483
--- /dev/null
+++ b/Java-base/tiles/src/src/site/apt/migration/configuration.apt
@@ -0,0 +1,160 @@
+~~ $Id$
+~~
+~~ 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.
+~~
+         -----------
+         Migrating Tiles configuration files
+         -----------
+
+{Reusing old Tiles configuration files}
+
+  With Tiles 2.1 and 2.2 it is possible to use old Struts-Tiles definition files, since
+  1.1 version.
+
+  To use this feature it is needed to:
+
+  * include the <<<tiles-compat-xxx.jar>>> package in the classpath;
+
+  * configure the compatibility definitions reader instance, that is able to
+  read old definition files.
+
+* Configuration
+
+  Override the
+  {{{../apidocs/org/apache/tiles/factory/BasicTilesContainerFactory.html#createDefinitionsReader(java.lang.Object,%20org.apache.tiles.TilesApplicationContext,%20org.apache.tiles.context.TilesRequestContextFactory)}createDefinitionsReader}}
+  method this way:
+
+---------------------------------------
+@Override
+protected DefinitionsReader createDefinitionsReader(Object context,
+        TilesApplicationContext applicationContext,
+        TilesRequestContextFactory contextFactory) {
+    return new CompatibilityDigesterDefinitionsReader();
+}
+---------------------------------------
+
+  You need to add a renderer for the "page" attribute type, that is in fact the "template" type.
+  So override the
+  {{{../apidocs/org/apache/tiles/factory/BasicTilesContainerFactory.html#registerAttributeRenderers(org.apache.tiles.renderer.impl.BasicRendererFactory,%20java.lang.Object,%20org.apache.tiles.TilesApplicationContext,%20org.apache.tiles.context.TilesRequestContextFactory,%20org.apache.tiles.TilesContainer,%20org.apache.tiles.evaluator.AttributeEvaluator)}registerAttributeRenderers}}
+  method.
+
+---------------------------------------
+@Override
+protected void registerAttributeRenderers(
+        BasicRendererFactory rendererFactory, Object context,
+        TilesApplicationContext applicationContext,
+        TilesRequestContextFactory contextFactory, TilesContainer container,
+        AttributeEvaluator evaluator) {
+    super.registerAttributeRenderers(rendererFactory, context,
+            applicationContext, contextFactory, container, evaluator);
+    TemplateAttributeRenderer templateRenderer = new TemplateAttributeRenderer();
+    templateRenderer.setApplicationContext(applicationContext);
+    templateRenderer.setRequestContextFactory(contextFactory);
+    templateRenderer.setEvaluator(evaluator);
+    rendererFactory.registerRenderer("page", templateRenderer);
+}
+---------------------------------------
+
+  <<WARNING!!!>> Configuration with initialization parameter has been deprecated! If you
+  still want to use it, please refer to the
+  {{{../../2.1/framework/migration/configuration.html}2.1 version of this page}}.
+
+
+Tiles configuration files translation
+
+  A better, and more powerful, choice is to rewrite the definition files, to use
+  the new features of Tiles 2.1.
+
+  Most of XML elements and attributes can be translated one-to-one or
+  many-to-one without losing functionality from the 1.1-1.3 to the 2.1 DTD
+  version.
+
+* Header
+
+  The new header to be put in your Tiles definitions files is:
+
+------------------------------------------------------------
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 2.1//EN"
+       "http://tiles.apache.org/dtds/tiles-config_2_1.dtd">
+------------------------------------------------------------
+
+* Definitions attributes
+
+*---------------------------------+--------------------------------+
+| <<Struts-Tiles>>                | <<Apache Tiles\u0099>>         |
+*---------------------------------+--------------------------------+
+| <<<\<component-definitions\>>>> | <<<\<tiles-definitions\>>>>    |
+| <<<\<tiles-definitions\>>>>     |                                |
+*---------------------------------+--------------------------------+
+| <<<page>>>                      | <<<template>>>                 |
+| <<<path>>>                      |                                |
+| <<<template>>>                  |                                |
+*---------------------------------+--------------------------------+
+| <<<controllerClass>>>           | <<<preparer>>> [1]             |
+| <<<controllerUrl>>>             |                                |
+*---------------------------------+--------------------------------+
+
+  * \[1\] The default behaviour of <<<preparer>>> is to create and use a
+  single instance of the specified class. Anyway it is still possible to use a
+  URL as a preparer under a Struts 1 environment by using the
+  {{{http://svn.apache.org/repos/asf/struts/struts1/trunk/tiles2/}Struts 1 - Apache Tiles\u0099}}
+  integration module, still under development.
+
+
+* Putting and adding attributes values
+
+  The <<<page>>> attribute type has been removed, use <<<template>>> instead.
+
+  The rest of the conversion is in the table below.
+
+*-----------------------+-----------------------------------------------+
+| <<Struts-Tiles>>      | <<Apache Tiles\u0099>>                        |
+*-----------------------+-----------------------------------------------+
+| <<<\<put\>>>>         | <<<\<put-attribute\>>>>                       |
+*-----------------------+-----------------------------------------------+
+| <<<\<putList\>>>>     | <<<\<put-list-attribute\>>>>                  |
+*-----------------------+-----------------------------------------------+
+| <<<\<add\>>>>         | <<<\<add-attribute\>>>>  [2]                  |
+|                       | <<<\<add-list-attribute\>>>>  [3]             |
+*-----------------------+-----------------------------------------------+
+| <<<content>>>         | <<<value>>>                                   |
+| <<<value>>>           |                                               |
+*-----------------------+-----------------------------------------------+
+| <<<direct="true">>>   | <<<type="string">>>                           |
+*-----------------------+-----------------------------------------------+
+
+  * \[2\] <<<\<add-attribute\>>>> is used when it is needed to add a single
+  attribute to a list attribute.
+
+  * \[3\] <<<\<add-list-attribute\>>>> is used when it is needed to a list
+  attribute as an element of another list attribute.
+
+  []
+
+   * Previous Migration Pages
+
+     ** {{{./index.html}Introduction }}
+
+   * Next Migration Pages
+
+     ** {{{./tags.html}Tiles JSP tags}}
+
+     ** {{{./apis.html}Java APIs considerations}}.
+
+     ** {{{./extension.html}Tiles extensions}}.
diff --git a/Java-base/tiles/src/src/site/apt/migration/extension.apt b/Java-base/tiles/src/src/site/apt/migration/extension.apt
new file mode 100644
index 000000000..fa6a83e38
--- /dev/null
+++ b/Java-base/tiles/src/src/site/apt/migration/extension.apt
@@ -0,0 +1,88 @@
+~~ $Id$
+~~
+~~ 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.
+~~
+         -----------
+         Tiles extensions migration
+         -----------
+
+Introduction
+
+  Tiles extensions is the part of Tiles where a major effort in refactoring is
+  needed.
+
+  The internal part of Tiles changed completely, not only in classes names, but
+  also in their behaviour.
+
+Writing definitions factories
+
+  Usually, Struts-Tiles extension writing meant writing a
+  <<<DefinitionsFactory>>> or a <<<FactorySet>>> implementation. Here you will
+  find how to convert your definitions factory to work correctly with Apache Tiles\u0099.
+
+* Requests management
+
+  Apache Tiles\u0099 is now technology-independent, that means that Apache Tiles\u0099 is no longer
+  bound to a Servlet environment. That means for you that all references to
+  <<<HttpServletRequest>>> and <<<HttpServletResponse>>> have been removed,
+  replacing them with <<<TilesRequestContext>>>
+
+* Definitions factory implementation
+
+  The most common way to implement a Definitions Factory is extending the
+  <<<UrlDefinitionsFactory>>> class, that contains code to load definitions,
+  resolve Locale-specific definitions, etc.
+
+  If you implemented <<<FactorySet>>>, here comes the bad news: it has been
+  <<removed>>! Getting a "key" to map different definitions factory was an
+  uncommon implementation detail. But it is easily reproducable, since you can
+  take the <<<TilesRequestContext>>> and calculate your "key". This key can be
+  used to map different <<<Definitions>>> instances, or to be given to an
+  instance of a class extending <<<Definitions>>>. Whatever you choose, it's
+  only a question of taste.
+
+Class and interfaces new names
+
+  The following is a conversion table between Struts-Tiles and Apache Tiles\u0099 class
+  names.
+
+*---------------------------------+---------------------------------+
+| <<Struts-Tiles>>                | <<Apache Tiles\u0099>>          |
+*---------------------------------+---------------------------------+
+| <<<ComponentDefinition>>>       | <<<Definition>>>                |
+*---------------------------------+---------------------------------+
+| <<<XmlDefinitionsSet>>>         | <<<Definitions>>>               |
+*---------------------------------+---------------------------------+
+| <<<XmlAttribute>>>              | <<<Attribute>>>                 |
+*---------------------------------+---------------------------------+
+| <<<ComponentListAttribute>>>    | <<<ListAttribute>>>             |
+*---------------------------------+---------------------------------+
+| <<<I18nFactorySet>>>            | <<<UrlDefinitionsFactory>>>     |
+*---------------------------------+---------------------------------+
+| <<<XmlParser>>>                 | <<<DigesterDefinitionsReader>>> |
+*---------------------------------+---------------------------------+
+
+   * Previous Migration Pages
+
+     ** {{{./index.html}Introduction }}
+
+     ** {{{./configuration.html}Tiles configuration files}}.
+
+     ** {{{./tags.html}Tiles JSP tags}}
+
+     ** {{{./apis.html}Java APIs considerations}}.
diff --git a/Java-base/tiles/src/src/site/apt/migration/index.apt b/Java-base/tiles/src/src/site/apt/migration/index.apt
new file mode 100644
index 000000000..50ec11485
--- /dev/null
+++ b/Java-base/tiles/src/src/site/apt/migration/index.apt
@@ -0,0 +1,57 @@
+~~ $Id$
+~~
+~~ 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.
+~~
+         -----------
+         Migration from Struts-Tiles
+         -----------
+
+Migration from Struts-Tiles
+
+  This tutorial is intended to provide a help when migrating from the previous
+  version of Tiles, known as
+  <<{{{http://struts.apache.org/1.3.8/struts-tiles/index.html}Struts-Tiles}}>>.
+
+  To use Tiles you need to put in your web application library directory:
+
+  * <<<tiles-api.jar>>>: it contains the API to manipulate and render Tiles.
+
+  * <<<tiles-core.jar>>>: it contains the "engine" of Tiles, and the basic
+  implementation of the APIs.
+
+  * <<<tiles-servlet.jar>>>: it contains the servlet support in Tiles.
+
+  * <<<tiles-jsp.jar>>>: it contains the JSP support to Tiles, i.e. JSP specific
+  classes and the tag library.
+
+  * <<<tiles-compat.jar>>>: it contains the compatibility layer of Tiles to
+  support Struts-Tiles 1.x XML definition files.
+
+* Further steps
+
+   * {{{./configuration.html}Tiles configuration files}}: How to migrate Tiles
+   configuration files, the file usually named <<<tiles-defs.xml>>>.
+
+   * {{{./tags.html}Tiles JSP tags}}: How to migrate Tiles JSP tags, the
+   <<<\<tiles:...\>>>> tags.
+
+   * {{{./apis.html}Java APIs considerations}}: Some information and warnings on
+   the different behaviour of the Tiles Java API.
+
+   * {{{./extension.html}Tiles extensions}}: How to migrate Tiles
+   extensions, with explanation of main changes in the code structure.
diff --git a/Java-base/tiles/src/src/site/apt/migration/tags.apt b/Java-base/tiles/src/src/site/apt/migration/tags.apt
new file mode 100644
index 000000000..72a8915db
--- /dev/null
+++ b/Java-base/tiles/src/src/site/apt/migration/tags.apt
@@ -0,0 +1,132 @@
+~~ $Id$
+~~
+~~ 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.
+~~
+         -----------
+         Translation of JSP tags
+         -----------
+
+Introduction
+
+  Tiles JSP tag library changed a lot, to be clearer and simpler than it was
+  before. This means that you need to change ALL of your JSP pages accordingly.
+
+Tag library inclusion
+
+  To include Tiles tag library, write this row on top of your JSP files:
+
+---------------------------------------------------------------------
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+---------------------------------------------------------------------
+
+Tags differences
+
+  Here is the toughest part: Apache Tiles\u0099 tags differ a lot comparing to Struts
+  Tiles. However, after the change you will notice that the JSP code will be
+  easier to understand.
+
+* The <<<\<tiles:insert\>>>> tag replacement
+
+  The <<<\<tiles:insert\>>>> of Struts-Tiles changed, in the sense that it has
+  been split in different parts and many attributes have been removed. The
+  changes are summarized in the table below.
+
+*---------------------------------+----------------------------------+
+| <<Struts-Tiles>>                | <<Apache Tiles\u0099>>           |
+*---------------------------------+----------------------------------+
+| <<<\<tiles:insert\>>>>          | <<<\<tiles:insertTemplate\>>>>   |
+|                                 | <<<\<tiles:insertAttribute\>>>>  |
+|                                 | <<<\<tiles:insertDefinition\>>>> |
+*---------------------------------+----------------------------------+
+| <<<component="definition_name">>> | Use <<<\<tiles:insertDefinition name="definition_name"\>>>> |
+*---------------------------------+----------------------------------+
+| <<<attribute="attribute_name">>>  | Use <<<\<tiles:insertAttribute name="attribute_name"\>>>>   |
+*---------------------------------+----------------------------------+
+| <<<page>>>                      | <<<template>>>                   |
+| <<<template>>>                  |                                  |
+*---------------------------------+----------------------------------+
+| <<<beanName="bean_name">>>         | <<<value="$\{bean_scopeScope.bean_name.bean_property\}">>> |
+| <<<beanProperty="bean_property">>> |                                                            |
+| <<<beanScope="bean_scope">>>       |                                                            |
+*---------------------------------+----------------------------------+
+| <<<controllerClass>>>           | <<<preparer>>> [1]               |
+| <<<controllerUrl>>>             |                                  |
+*---------------------------------+----------------------------------+
+
+
+  * \[1\] The default behaviour of <<<preparer>>> is to create and use a
+  single instance of the specified class. Anyway it is still possible to use a
+  URL as a preparer under a Struts 1 environment by using the
+  {{{http://svn.apache.org/repos/asf/struts/struts1/trunk/tiles2/}Struts 1 - Apache Tiles\u0099}}
+  integration module, still under development.
+
+* Putting and adding attributes values
+
+  The <<<page>>> attribute type has been removed, use <<<template>>> instead.
+
+  The rest of the conversion is in the table below.
+
+*-------------------------+-----------------------------------------------+
+| <<Struts-Tiles>>        | <<Apache Tiles\u0099>>                        |
+*-------------------------+-----------------------------------------------+
+| <<<\<tiles:put\>>>>     | <<<\<tiles:putAttribute\>>>>                  |
+*-------------------------+-----------------------------------------------+
+| <<<\<tiles:putList\>>>> | <<<\<tiles:putAttributeList\>>>>              |
+*-------------------------+-----------------------------------------------+
+| <<<\<tiles:add\>>>>     | <<<\<tiles:addAttribute\>>>>  [2]             |
+|                         | <<<\<tiles:addListAttribute\>>>>  [3]         |
+*-------------------------+-----------------------------------------------+
+| <<<content>>>           | <<<value>>>                                   |
+| <<<value>>>             |                                               |
+*-------------------------+-----------------------------------------------+
+| <<<direct="true">>>     | <<<type="string">>>                           |
+*-------------------------+-----------------------------------------------+
+| <<<beanName="bean_name">>>         | <<<value="$\{bean_scopeScope.bean_name.bean_property\}">>> |
+| <<<beanProperty="bean_property">>> |                                                            |
+| <<<beanScope="bean_scope">>>       |                                                            |
+*---------------------------------+----------------------------------+
+
+  * \[2\] <<<\<tiles:addAttribute\>>>> is used when it is needed to add a single
+  attribute to a list attribute.
+
+  * \[3\] <<<\<tiles:addListAttribute\>>>> is used when it is needed to a list
+  attribute as an element of another list attribute.
+
+* Other changes
+
+*---------------------------------+--------------------------------------------+
+| <<Struts-Tiles>>                | <<Apache Tiles\u0099>>                     |
+*---------------------------------+--------------------------------------------+
+| <<<\<tiles:get\>>>>             | <<<\<tiles:insertAttribute\>>>>            |
+*---------------------------------+--------------------------------------------+
+| <<<\<tiles:definition scope="scope"\>>>> | Removed, definitions are created in request scope. |
+*---------------------------------+--------------------------------------------+
+| <<<\<tiles:initComponentDefinitions\>>>> | <<<\<tiles:initContainer\>>>>     |
+*---------------------------------+--------------------------------------------+
+
+   * Previous Migration Pages
+
+     ** {{{./index.html}Introduction }}
+
+     ** {{{./configuration.html}Tiles configuration files}}.
+
+   * Next Migration Pages
+
+     ** {{{./apis.html}Java APIs considerations}}.
+
+     ** {{{./extension.html}Tiles extensions}}.
diff --git a/Java-base/tiles/src/src/site/apt/security/index.apt b/Java-base/tiles/src/src/site/apt/security/index.apt
new file mode 100644
index 000000000..5de299406
--- /dev/null
+++ b/Java-base/tiles/src/src/site/apt/security/index.apt
@@ -0,0 +1,28 @@
+~~ $Id$
+~~
+~~ 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.
+~~
+         -----------
+         Security bulletins
+         -----------
+
+Security bulletins
+
+  Here are collected all security bulletins about Tiles.
+
+  * {{{./security-bulletin-1.html}Security Bulletin 1}}.
diff --git a/Java-base/tiles/src/src/site/apt/security/security-bulletin-1.apt b/Java-base/tiles/src/src/site/apt/security/security-bulletin-1.apt
new file mode 100644
index 000000000..8d5d6a174
--- /dev/null
+++ b/Java-base/tiles/src/src/site/apt/security/security-bulletin-1.apt
@@ -0,0 +1,72 @@
+~~ $Id$
+~~
+~~ 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.
+~~
+         -----------
+         Security bulletin 1
+         -----------
+
+Security bulletin 1
+
+* Summary
+
+  EL expressions in JSP using some Tiles JSP tags are evaluated twice.
+
+*-------------------------+-----------+
+| Who should read this    | All Tiles 2.1 developers |
+*-------------------------+-----------+
+| Impact of vulnerability | Remote server context exposure |
+*-------------------------+-----------+
+| Maximum security rating | High (read-only exposure) |
+*-------------------------+-----------+
+| Recommendation          | Developers should not install Tiles 2.1.1 under a production environment, |
+|                         | upgrade to Tiles 2.1.2 |
+*-------------------------+-----------+
+| Affected Software       | Tiles 2.1.0/2.1.1 (Tiles 2.0.x versions are safe) |
+*-------------------------+-----------+
+| Original JIRA Ticket    | {{{https://issues.apache.org/jira/browse/TILES-351}TILES-351}}       |
+*-------------------------+-----------+
+| Reporter                | Antonio Petrelli (Tiles PMC member) |
+*-------------------------+-----------+
+
+* Problem
+
+  Tiles 2.1.x allows, with the
+  {{{../tutorial/advanced/el-support.html}correct configuration}},
+  to use EL expressions in Tiles configuration files.
+  
+  The problem is that, if attribute values or templates are defined using
+  some JSP tags (tiles:putAttribute, tiles:insertTemplate), the EL expression
+  is evaluated twice, one by the container, one by the ELAttributeEvaluator
+  class.
+  
+  Now, if at the first evaluation the EL expression is connected to a
+  user-entered content, it could be maliciously exploited to access the
+  server context.
+  
+  Therefore, there could be an unwanted exposure of server data or XSS attacks.
+
+* Solution
+
+  The API and the core have been modified to separate the expression evaluation
+  from the attribute/template manipulation made by JSP tags in a safe way.
+
+  Since Tiles 2.1.1 is still in beta, the recommendation is not to install it
+  in a production environment. A release, in this case, is not necessary.
+  Experimenter can download the latest version of Tiles from the
+  {{{http://svn.apache.org/repos/asf/tiles/framework/trunk/}SVN repository}}.
diff --git a/Java-base/tiles/src/src/site/apt/selenium.apt b/Java-base/tiles/src/src/site/apt/selenium.apt
new file mode 100755
index 000000000..4be3bd5e3
--- /dev/null
+++ b/Java-base/tiles/src/src/site/apt/selenium.apt
@@ -0,0 +1,166 @@
+~~ $Id$
+~~
+~~ 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.
+~~
+         -----------
+         Selenium Testing
+         -----------
+
+Selenium Testing
+
+ <<{{{http://selenium.openqa.org}Selenium}}>> is a test tool for web
+ applications. Unlike HtmlUnit or HttpUnit tests which <simulate> a browser,
+ Selenium tests run directly in a real browser such as Firefox or Internet
+ Explorer. The Selenium JavaScript code is deployed alongside your running
+ application, and interacts with it just as your users do.
+
+ Apache Tiles\u0099 uses Selenium for functional testing of the example apps.
+ The following example apps include Selenium tests:
+
+  * Tiles Test
+
+* Install
+
+ Selenium is available in OpenQA's Maven repository, so no installation is
+ necessary.
+
+ However, you may want to download the Selenium distribution (which includes
+ the documentation) from
+ {{{http://www.openqa.org/selenium-core/download.action}
+ http://www.openqa.org/selenium-core/download.action}}.
+
+ While you're there, also install the Firefox plugin <<Selenium IDE>> from
+ {{{http://www.openqa.org/selenium-ide/}
+ http://www.openqa.org/selenium-ide/}}.
+
+* Run Selenium tests the easy way
+
+  To run Selenium tests you need to add a configuration parameter in your <<<settings.xml>>> file.
+
+------------------------------
+<settings xmlns="http://maven.apache.org/POM/4.0.0"
+	  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
+                      http://maven.apache.org/xsd/settings-1.0.0.xsd">
+...
+	<profiles>
+	...
+		<profile>
+			<id>run-selenium</id>
+			<properties>
+				<cargo.tomcat6x.home>/tomcat/installation/directory</cargo.tomcat6x.home>
+			</properties>
+    	</profile>
+    ...
+    </profiles>
+</settings>
+------------------------------
+
+  After that, if you have Firefox installed, you can launch Selenium tests in the command line:
+
+------------------------------
+mvn verity -Prun-selenium
+------------------------------
+
+* Package
+
+ <<Package>> the webapp with the 'selenium' profile activated.
+
+ The {{{http://svn.apache.org/viewvc/struts/sandbox/trunk/tiles/tiles-test/pom.xml
+?view=markup}tiles-test pom}} includes a 'selenium' profile that will
+
+  * unpack the Selenium jar under 'target'
+
+  * copy the 'core' directory from the unpacked Selenium jar into the
+  webapp
+
+  * copy any files in 'src/test/selenium' into the webapp
+
+  []
+
++-----+
+mvn package -P selenium
++-----+
+
+  The webapp will contain the following additional directories: 'selenium/core'
+  and 'selenium/tests'.
+
+* Deploy
+
+  <<Deploy>> the webapp to your favorite container. The Cargo plugin is
+  configured to make this easy:
+
++-----+
+mvn package cargo:start -P selenium
+
+   or
+
+mvn package cargo:start -P selenium -Dcargo.tomcat5x.home=/path/to/tomcat5
++-----+
+
+
+* Run
+
+ <<Run>> the tests with the Selenium TestRunner.
+
+ * Visit <<<http://localhost:8080/<appname>/selenium/core/TestRunner.html>>>
+
+ * Click 'go' in the top left frame to load the TestSuite.html page
+
+ * Click 'All' in the top right frame to run the tests
+
+ []
+
+ <<Run>> the tests <automatically>.
+
+ * Check the 'Auto-run' box before clicking 'go' in the top left frame.
+
+ []
+
+ After it runs the tests automatically, Selenium can <<<POST>>> the results to
+ a URL you supply.  If you accept the default, and nothing is there to process
+ the request, you will see a 404 Not Found error page in the bottom frame.
+
+
+* Edit
+
+  <<Edit>> an existing test, or write a new one.
+
+  If you add a new test, remember to add it to src/test/selenium/TestSuite.html
+  so the TestRunner will find it.
+
+** Selenium IDE
+
+  The Selenium IDE Firefox plugin is the easiest way to edit tests. With the
+  example app running, open the HTML file (src/test/selenium/TestSomething.html)
+  from your svn checkout of Apache Tiles\u0099. Use the IDE to edit and run the test, and
+  save your changes.
+
+  <<Note>>: Your changes will not be visible to the TestRunner in the deployed
+  webapp unless you re-package and deploy it.
+
+** HTML Editor
+
+  Selenium tests are written in plain HTML tables, so you may edit them with any
+  text editor.
+
+  If you prefer to edit the tests 'in place' in the running webapp, simply copy
+  the files back to your svn checkout directory and commit the changes (or submit
+  a patch).
+
+
diff --git a/Java-base/tiles/src/src/site/apt/tutorial/advanced/attribute-rendering.apt b/Java-base/tiles/src/src/site/apt/tutorial/advanced/attribute-rendering.apt
new file mode 100644
index 000000000..97a53955f
--- /dev/null
+++ b/Java-base/tiles/src/src/site/apt/tutorial/advanced/attribute-rendering.apt
@@ -0,0 +1,82 @@
+~~ $Id$
+~~
+~~ 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.
+~~
+         -----------
+         Attribute rendering
+         -----------
+
+Attribute rendering
+
+  Attribute rendering behaviour can be customized. The "type"
+  of an attribute can be still <<<string>>>, <<<definition>>> or <<<template>>>
+  but you can define new types or use a class name directly.
+
+Default behaviour
+
+  The default behaviour of Tiles is compatible with Tiles 2.0 and it applies
+  both to XML definition files and JSP tags. Tiles follows these steps:
+
+  * If the type is not specified:
+
+  ** if the value is a valid definition name, the definition is rendered;
+
+  ** if the value starts with a '/', a template will be rendered;
+
+  ** otherwise, a string will be rendered.
+
+  * If the type is specified:
+
+  ** if the type is <<<string>>>, <<<definition>>> or <<<template>>>, it will
+  be rendered like in Tiles 2.0;
+
+  ** otherwise, Tiles tries to instantiate (only once) a class whose name is
+  specified in the "type" of the attribute. If an error occurs, it pops up as
+  a runtime exception.
+
+Customize attribute rendering
+
+  With Tiles 2.1+ you can customize rendering in three ways:
+
+  * specifying new renderers;
+
+  * overriding the default renderer for untyped attributes;
+
+  * specifying a new renderer factory.
+
+* Custom attribute renderers
+
+  If you don't want to use class names as attribute types, you can use new
+  "named" custom attribute renderers. You can do it by overriding the
+  {{{../../apidocs/org/apache/tiles/factory/BasicTilesContainerFactory.html#method_summary}registerAttributeRenderers}}
+  of <<<BasicTilesContainerFactory>>> if you are using Java-based configuration.
+
+* Custom default attribute renderer
+
+  The behaviour of Tiles when the type of an attribute is not specified can also be
+  customized. You can do it by overriding the
+  {{{../../apidocs/org/apache/tiles/factory/BasicTilesContainerFactory.html#method_summary}createDefaultAttributeRenderer}}
+  of <<<BasicTilesContainerFactory>>> if you are using Java-based configuration.
+
+* Custom attribute renderer factory
+
+  The attribute renderer factory can be completely customized, leaving to you
+  the maximum freedom of choice in the attribute renderer creation. You can
+  specify the factory's implementation by overriding the
+  {{{../../apidocs/org/apache/tiles/factory/BasicTilesContainerFactory.html#method_summary}createRendererFactory}}
+  of <<<BasicTilesContainerFactory>>> if you are using Java-based configuration.
diff --git a/Java-base/tiles/src/src/site/apt/tutorial/advanced/el-support.apt b/Java-base/tiles/src/src/site/apt/tutorial/advanced/el-support.apt
new file mode 100644
index 000000000..ec728de04
--- /dev/null
+++ b/Java-base/tiles/src/src/site/apt/tutorial/advanced/el-support.apt
@@ -0,0 +1,98 @@
+~~ $Id$
+~~
+~~ 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.
+~~
+         -----------
+         Expression Language (EL) support
+         -----------
+
+Expression Language support
+
+  With Tiles it is possible to use expression languages not only in JSP pages, but also in XML
+  definition files.
+
+  Currently supported languages are Unified EL (as in javax.el), i.e. the language used in JSP code,
+  {{{http://mvel.codehaus.org/}MVEL}} and {{{http://commons.apache.org/ognl/}OGNL}}.
+
+* Configuration
+
+  By default, Tiles does not use an expression language, attribute values are simply used as they are.
+  
+  <<<CompleteAutoloadTilesContainerFactory>>> enables support of Unified EL, MVEL and OGNL as follows:
+  
+  - an attribute expression starting with "MVEL:" or "OGNL:" is interpreted in one of those languages.
+  - otherwise, the parts of the expression between the braces in <<<$\{...\}>>> are interpreted in Unified EL.  
+
+* Unified EL support
+
+  The EL language is supported since Tiles 2.1.
+
+  Let's use this example:
+
+------------------------------------
+  <definition name="test.composite.el.definition" templateExpression="${layout}"
+        preparer="org.apache.tiles.test.preparer.RequestSettingViewPreparer">
+      <put-attribute name="title"  value="This is a configured composite definition."/>
+      <put-attribute name="header" value="/header.jsp"/>
+      <put-attribute name="body"   expression="${requestScope.body}"/>
+  </definition>
+------------------------------------
+
+  Before rendering the definition:
+
+  * The template name will be taken from the "layout" attribute, searched in every scope.
+
+  * The body will be taken from the "body" attribute in request scope.
+
+* {MVEL Support}
+
+  Let's use this example:
+
+------------------------------------
+  <definition name="test.composite.mvel.definition" templateExpression="MVEL:layout"
+        preparer="org.apache.tiles.test.preparer.RequestSettingViewPreparer">
+      <put-attribute name="title"  value="This is a configured composite definition."/>
+      <put-attribute name="header" value="/header.jsp"/>
+      <put-attribute name="body"   expression="MVEL:requestScope.body"/>
+  </definition>
+------------------------------------
+
+  Before rendering the definition:
+
+  * The template name will be taken from the "layout" attribute, searched in every scope.
+
+  * The body will be taken from the "body" attribute in request scope.
+
+* {OGNL Support}
+
+  Let's use this example:
+
+------------------------------------
+  <definition name="test.composite.mvel.definition" templateExpression="OGNL:layout"
+        preparer="org.apache.tiles.test.preparer.RequestSettingViewPreparer">
+      <put-attribute name="title"  value="This is a configured composite definition."/>
+      <put-attribute name="header" value="/header.jsp"/>
+      <put-attribute name="body"   expression="OGNL:requestScope.body"/>
+  </definition>
+------------------------------------
+
+  Before rendering the definition:
+
+  * The template name will be taken from the "layout" attribute, searched in every scope.
+
+  * The body will be taken from the "body" attribute in request scope.
diff --git a/Java-base/tiles/src/src/site/apt/tutorial/advanced/index.apt b/Java-base/tiles/src/src/site/apt/tutorial/advanced/index.apt
new file mode 100644
index 000000000..2f98cbe76
--- /dev/null
+++ b/Java-base/tiles/src/src/site/apt/tutorial/advanced/index.apt
@@ -0,0 +1,50 @@
+~~ $Id$
+~~
+~~ 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.
+~~
+         -----------
+         Tiles Advanced Topics
+         -----------
+
+Tiles Advanced Topics
+
+  In this section, advanced usage of Tiles is discussed. These topics let you
+  do more complicated tasks, like composing pages one inside another, localize
+  your pages, etc.
+
+  [[1]] {{{./nesting-extending.html}Nesting and Extending Definitions}}
+
+  [[2]] {{{./list-attributes.html}List Attributes}}
+
+  [[3]] {{{./runtime.html}Runtime Composition}}
+
+  [[4]] {{{./preparer.html}View Preparers}}
+
+  [[5]] {{{./utils.html}Rendering Utilities}}
+
+  [[6]] {{{./l10n.html}Tiles Localization}}
+
+  [[7]] {{{./wildcard.html}Wildcard support}}
+
+  [[8]] {{{./el-support.html}EL support}}
+
+  [[9]] {{{./attribute-rendering.html}Attribute rendering}}
+
+  [[10]] {{{./multiple-containers.html}Using multiple containers}}
+
+  [[11]] {{{./security.html}Security}}
diff --git a/Java-base/tiles/src/src/site/apt/tutorial/advanced/l10n.apt b/Java-base/tiles/src/src/site/apt/tutorial/advanced/l10n.apt
new file mode 100644
index 000000000..80db80b87
--- /dev/null
+++ b/Java-base/tiles/src/src/site/apt/tutorial/advanced/l10n.apt
@@ -0,0 +1,135 @@
+~~ $Id$
+~~
+~~ 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.
+~~
+         -----------
+         Tiles Localization
+         -----------
+
+Localization support
+
+  Customizing pages for different locales in a common practice: in real-world
+  websites you can see different sites for different languages and countries.
+
+  It can be a matter of changing the layout (for example, in Arab countries the
+  menu should stay on the right, instead of the left), or providing alternate
+  content.
+
+* Creating localized definitions
+
+  Localization is immediately available. To use the benefits of localization you
+  have to create different Tiles definition files for each locale you want to
+  support: it's simply a matter of appending the locale code at the end of the
+  file name (just like <<<.properties>>> files in resource bundles).
+
+  For example, if you have the <<<tiles.xml>>> file and you want to support
+  French and Italian locale, you have to create at least three files:
+
+--------------------------------
+tiles.xml
+tiles_fr.xml
+tiles_it.xml
+--------------------------------
+
+  You can also distinguish between different languages in different country. So
+  if you want to distinguish between British English and American English, you
+  can create these files:
+
+--------------------------------
+tiles_en_GB.xml
+tiles_en_US.xml
+--------------------------------
+
+  and so on.
+
+* Inheritance between localizations
+
+  If you want to support different locales, you don't have to rewrite all the
+  definitions, but only those that differ from the main definitions file. In
+  other words, locale-specific definition files contains the "overrides" to the
+  default definitions.
+
+  For example, suppose that the following definition is declared in
+  <<<tiles.xml>>>:
+
+------------------------------------
+<definition name="myapp.homepage" template="/layouts/classic.jsp">
+  <put-attribute name="title" value="Tiles tutorial homepage" />
+  <put-attribute name="header" value="/tiles/banner.jsp" />
+  <put-attribute name="menu" value="/tiles/common_menu.jsp" />
+  <put-attribute name="body" value="myapp.homepage.body" />
+  <put-attribute name="footer" value="/tiles/credits.jsp" />
+</definition>
+
+<definition name="myapp.homepage.body" template="/layouts/three_rows.jsp">
+  <put-attribute name="one" value="/tiles/headlines.jsp" />
+  <put-attribute name="two" value="/tiles/topics.jsp" />
+  <put-attribute name="one" value="/tiles/comments.jsp" />
+</definition>
+------------------------------------
+
+  In <<<tiles_it.xml>>> there is a new declaration of <<<myapp.homepage>>>
+  definition:
+
+------------------------------------
+<definition name="myapp.homepage" template="/layouts/classic.jsp">
+  <put-attribute name="title" value="Pagina iniziale del tutorial di Tiles" />
+  <put-attribute name="header" value="/tiles/banner.jsp" />
+  <put-attribute name="menu" value="/tiles/common_menu.jsp" />
+  <put-attribute name="body" value="myapp.homepage.body" />
+  <put-attribute name="footer" value="/tiles/credits.jsp" />
+</definition>
+------------------------------------
+
+  Using "it" locale, the title will be different from the default, while the
+  rest remains the same.
+  
+  Notice that the <<<myapp.homepage.body>>> definition is the one defined in
+  the default definitions file: you still can reference to the default
+  definitions, both when composing and when extending.
+  
+  You can also override a <<definition that is extended>>. In this case, when
+  resolving inheritance, the overridden definition will be taken as a basis.
+  For example, if in <<<tiles.xml>>> there are the following definitions:
+
+------------------------------------
+<definition name="myapp.page.common" template="/layouts/classic.jsp">
+  <put-attribute name="header" value="/tiles/banner.jsp" />
+  <put-attribute name="menu" value="/tiles/common_menu.jsp" />
+  <put-attribute name="footer" value="/tiles/credits.jsp" />
+</definition>
+
+<definition name="myapp.bugs" extends="myapp.page.common">
+  <put-attribute name="title" value="Bugs" />
+  <put-attribute name="body" value="myapp.homepage.body" />
+</definition>
+------------------------------------
+
+  If in <<<tiles_it.xml>>> you define the following definition:
+
+------------------------------------
+<definition name="myapp.page.common" template="/layouts/classic.jsp">
+  <put-attribute name="header" value="/tiles/banner_it.jsp" />
+  <put-attribute name="menu" value="/tiles/common_menu_it.jsp" />
+  <put-attribute name="footer" value="/tiles/credits_it.jsp" />
+</definition>
+------------------------------------
+
+  The <<<myapp.bugs>>> will extend the latter definition, and not the default!
+  This is useful if you want to change an abstract definition for a locale,
+  without redefining all the definitions.
diff --git a/Java-base/tiles/src/src/site/apt/tutorial/advanced/list-attributes.apt b/Java-base/tiles/src/src/site/apt/tutorial/advanced/list-attributes.apt
new file mode 100644
index 000000000..a6a58e83f
--- /dev/null
+++ b/Java-base/tiles/src/src/site/apt/tutorial/advanced/list-attributes.apt
@@ -0,0 +1,96 @@
+~~ $Id$
+~~
+~~ 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.
+~~
+         -----------
+         List Attributes
+         -----------
+
+List Attributes
+
+  Up to now we have seen simple attributes, i.e. attributes that have a simple
+  value: a template, a string or a definition. But there are cases where you
+  need a <collection> of values, for example a list of definitions to be
+  redendered one below the other.
+
+* Simple usage
+
+  To include a list attribute you can use the <<<\<put-list-attribute\>>>> tag
+  in your Tiles definitions file:
+
+---------------------------------------
+<definition name="myapp.homepage.body" template="/layouts/variable_rows.jsp">
+  <put-list-attribute name="items">
+    <add-attribute value="/tiles/banner.jsp" />
+    <add-attribute value="/tiles/common_menu.jsp" />
+    <add-attribute value="/tiles/credits.jsp" />
+  </put-list-attribute>
+</definition>
+---------------------------------------
+
+  In your template page, you can read the list attribute iterating over its
+  elements:
+
+---------------------------------------
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles-extras" prefix="tilesx" %>
+<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
+<tilesx:useAttribute id="list" name="items" classname="java.util.List" />
+<c:forEach var="item" items="${list}">
+  <tiles:insertAttribute value="${item}" flush="true" />
+  <br/>
+</c:forEach>
+---------------------------------------
+
+  The list attribute is first converted into a scripting variable; after that
+  it is iterated using the <<<\<c:forEach\>>>> tag. The compound attributes are
+  then rendered one after the other.
+
+* {List attribute inheritance}
+
+  When you extend a definition that contains a list attribute, you can
+  "inherit" its elements. For example:
+
+---------------------------------------
+<definition name="myapp.homepage.body" template="/layouts/variable_rows.jsp">
+  <put-list-attribute name="items">
+    <add-attribute value="/tiles/banner.jsp" />
+    <add-attribute value="/tiles/common_menu.jsp" />
+    <add-attribute value="/tiles/credits.jsp" />
+  </put-list-attribute>
+</definition>
+
+<definition name="myapp.homepage.body.extended" extends="myapp.homepage.body">
+  <put-list-attribute name="items" inherit="true">
+    <add-attribute value="/tiles/greetings.jsp" />
+  </put-list-attribute>
+</definition>
+---------------------------------------
+
+  In this case, the <<<myapp.homepage.body.extended>>> has the <<<items>>>
+  attribute that inherits the content of the <<<items>>> attribute of its
+  parent definition. In other words, the <<<items>>> attribute will container
+  the following elements:
+
+  * /tiles/banner.jsp
+
+  * /tiles/common_menu.jsp
+
+  * /tiles/credits.jsp
+
+  * /tiles/greetings.jsp
diff --git a/Java-base/tiles/src/src/site/apt/tutorial/advanced/multiple-containers.apt b/Java-base/tiles/src/src/site/apt/tutorial/advanced/multiple-containers.apt
new file mode 100644
index 000000000..84b93aaf8
--- /dev/null
+++ b/Java-base/tiles/src/src/site/apt/tutorial/advanced/multiple-containers.apt
@@ -0,0 +1,86 @@
+~~ $Id$
+~~
+~~ 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.
+~~
+         -----------
+         Using multiple containers
+         -----------
+
+Defining multiple containers
+
+  It is possible to use more that one Tiles container in your application.
+
+* Configuration
+
+  To use an alternate container, you need to override the
+  {{{../../apidocs/org/apache/tiles/startup/AbstractTilesInitializer.html#method_summary}getContainerKey}}
+  method of <<<AbstractTilesInitializer>>> this way:
+
+------------------------------------
+public class TestAlternateTilesListener extends AbstractTilesListener {
+
+    /** {@inheritDoc} */
+    @Override
+    protected TilesInitializer createTilesInitializer() {
+        return new TestAlternateTilesInitializer();
+    }
+
+    /**
+     * Test Tiles initializer for Tiles initialization of the alternate container.
+     */
+    private static class TestAlternateTilesInitializer extends AbstractTilesInitializer {
+
+        // Other customizations go here.
+
+        /** {@inheritDoc} */
+        @Override
+        protected String getContainerKey(
+                TilesApplicationContext applicationContext) {
+            return "myContainerKey";
+        }
+    }
+}
+------------------------------------
+
+Selecting one non-default container
+
+  Once defined, it is possible to select a non-default container through Java
+  or JSP
+
+* Selection through Java
+
+  It is possible to use, for the current request, a different container
+  stored under another key, by using
+  {{{../../apidocs/org/apache/tiles/access/TilesAccess.html#method_summary}<<<setCurrentContainer>>>}}
+  method of TilesAccess class. For example:
+
+------------------------------------
+TilesAccess.setCurrentContainer(request, applicationContext, "myContainerKey");
+------------------------------------
+
+  If the last parameter is <<<null>>>, the default container is selected.
+
+* Selection through JSP
+
+  The current container can be selected also through the use of JSP:
+
+------------------------------------
+<tiles:setCurrentContainer containerKey="myContainerKey" />
+------------------------------------
+
+  If the <<<containerKey>>> attribute is not present, the default container is selected.
diff --git a/Java-base/tiles/src/src/site/apt/tutorial/advanced/nesting-extending.apt b/Java-base/tiles/src/src/site/apt/tutorial/advanced/nesting-extending.apt
new file mode 100644
index 000000000..531e298d4
--- /dev/null
+++ b/Java-base/tiles/src/src/site/apt/tutorial/advanced/nesting-extending.apt
@@ -0,0 +1,168 @@
+~~ $Id$
+~~
+~~ 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.
+~~
+         -----------
+         Nesting and Extending Definitions
+         -----------
+
+Nesting Definitions
+
+  Sometimes it is useful to have a structured page with, say, a structured body.
+  Typically, there is a main layout (for example, the "classic" layout) and the
+  body is made of certain number of sections. In this case, nesting a definition
+  (the one for the body) inside another definition (the main layout) can be
+  useful.
+
+* {Named subdefinitions}
+
+  Tiles supports nesting definitions natively. One way of using nested definitions
+  is creating a named "subdefinition" and using it as an attribute. For example:
+
+------------------------------------
+<definition name="myapp.homepage.body" template="/layouts/three_rows.jsp">
+  <put-attribute name="one" value="/tiles/headlines.jsp" />
+  <put-attribute name="two" value="/tiles/topics.jsp" />
+  <put-attribute name="one" value="/tiles/comments.jsp" />
+</definition>
+
+<definition name="myapp.homepage" template="/layouts/classic.jsp">
+  <put-attribute name="title" value="Tiles tutorial homepage" />
+  <put-attribute name="header" value="/tiles/banner.jsp" />
+  <put-attribute name="menu" value="/tiles/common_menu.jsp" />
+  <put-attribute name="body" value="myapp.homepage.body" />
+  <put-attribute name="footer" value="/tiles/credits.jsp" />
+</definition>
+------------------------------------
+
+  The <<<myapp.homepage.body>>> definition will be put inside the
+  <<<myapp.homepage>>>, by putting it inside its <<<body>>> attribute. You will
+  be seeing the definition one inside the other.
+
+* {Anonymous nested definitions}
+
+  What you can do with named subdefinitions can be done with nested anonymous
+  definitions. The above example can be rewritten in:
+  
+------------------------------------
+<definition name="myapp.homepage.body" template="/layouts/three_rows.jsp">
+  <put-attribute name="one" value="/tiles/headlines.jsp" />
+  <put-attribute name="two" value="/tiles/topics.jsp" />
+  <put-attribute name="one" value="/tiles/comments.jsp" />
+</definition>
+
+<definition name="myapp.homepage" template="/layouts/classic.jsp">
+  <put-attribute name="title" value="Tiles tutorial homepage" />
+  <put-attribute name="header" value="/tiles/banner.jsp" />
+  <put-attribute name="menu" value="/tiles/common_menu.jsp" />
+  <put-attribute name="body">
+    <definition template="/layouts/three_rows.jsp">
+      <put-attribute name="one" value="/tiles/headlines.jsp" />
+      <put-attribute name="two" value="/tiles/topics.jsp" />
+      <put-attribute name="one" value="/tiles/comments.jsp" />
+    </definition>
+  </put-attribute>
+  <put-attribute name="footer" value="/tiles/credits.jsp" />
+</definition>
+------------------------------------
+
+  The anonymous definition put under the "body" attribute can be used only by
+  the surrounding definition. Moreover, you can nest a definition into a nested
+  definition, with the desired level of depth.
+
+* {Cascaded attributes}
+
+  Attributes defined into a definition can be cascaded to be available to all
+  nested definitions and templates. For example the
+  {{{./nesting-extending.html#Named_subdefinitions}sample definition}} detailed above can be rewritten
+  this way:
+
+------------------------------------
+<definition name="myapp.homepage" template="/layouts/classic.jsp">
+  <put-attribute name="title" value="Tiles tutorial homepage" />
+  <put-attribute name="header" value="/tiles/banner.jsp" />
+  <put-attribute name="menu" value="/tiles/common_menu.jsp" />
+  <put-attribute name="body" value="/layouts/three_rows.jsp" />
+  <put-attribute name="footer" value="/tiles/credits.jsp" />
+
+  <put-attribute name="one" value="/tiles/headlines.jsp" cascade="true" />
+  <put-attribute name="two" value="/tiles/topics.jsp" cascade="true" />
+  <put-attribute name="one" value="/tiles/comments.jsp" cascade="true" />
+</definition>
+------------------------------------
+
+  The template of <<<myapp.homepage.body>>> definitionhas been used as the
+  <<<body>>> attribute in the <<<myapp.homepage>>> definition. All of the
+  attributes of <<<myapp.homepage.body>>> has been then moved as attributes
+  of <<<myapp.homepage>>> definition, but with the addition of the "cascade"
+  flag.
+
+Extending Definitions
+
+  You can extend definitions like a Java class. The concepts of <abstract
+  definition>, <extension> and <override> are available.
+  
+  * <<Abstract definition>>: it is a definition in which the template attributes
+  are not completely filled. They are useful to create a base page and a number
+  of extending definitions, reusing already created layout. For example:
+
+------------------------------------
+<definition name="myapp.page.common" template="/layouts/classic.jsp">
+  <put-attribute name="header" value="/tiles/banner.jsp" />
+  <put-attribute name="menu" value="/tiles/common_menu.jsp" />
+  <put-attribute name="footer" value="/tiles/credits.jsp" />
+</definition>
+------------------------------------
+
+  * <<Definition extension>>: a definition can inherit from another definition,
+  to reuse an already made (abstract or not) definition:
+
+------------------------------------
+<definition name="myapp.homepage" extends="myapp.page.common">
+  <put-attribute name="title" value="Tiles tutorial homepage" />
+  <put-attribute name="body" value="myapp.homepage.body" />
+</definition>
+------------------------------------
+
+  In this case, the <<<header>>>, <<<menu>>> and <<<footer>>> are inherited from
+  the <<<myapp.page.common>>> definition, while the rest is defined inside the
+  "concrete" definition.
+
+  * <<Template and attribute override>>: when extending a definition, its
+  template and attributes can be overridden.
+  
+    ** Overriding a template:
+    
+------------------------------------
+<definition name="myapp.homepage.alternate" extends="myapp.homepage"
+    template="/layouts/alternate.jsp" />
+------------------------------------
+
+    The definition has the same attributes, but its template changed. The result
+    is that the content is the same, but the layout is different.
+    
+    ** Overriding attributes:
+
+------------------------------------
+<definition name="myapp.homepage.customer" extends="myapp.homepage">
+  <put-attribute name="menu" value="/tiles/common_menu_for_customers.jsp" />
+</definition>
+------------------------------------
+    
+    In this case, the page will have the same appearance as the
+    <<<myapp.homepage>>> definition, but its menu subpage is different.
diff --git a/Java-base/tiles/src/src/site/apt/tutorial/advanced/preparer.apt b/Java-base/tiles/src/src/site/apt/tutorial/advanced/preparer.apt
new file mode 100644
index 000000000..0cdf30a1c
--- /dev/null
+++ b/Java-base/tiles/src/src/site/apt/tutorial/advanced/preparer.apt
@@ -0,0 +1,70 @@
+~~ $Id$
+~~
+~~ 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.
+~~
+         -----------
+         Tiles View Preparers
+         -----------
+
+View Preparers
+
+  Sometimes a definition, before it is rendered, needs to be "prepared". For
+  example when showing a menu, the menu structure must be created and stored
+  in the request scope.
+
+  For this reason, a <<View Preparer>> can be used: it is called <<before>> the
+  definition is rendered, so all the things needed to render correctly the
+  definition can be prepared.
+
+* Creating a view preparer
+
+  A View Preparer is simply a class that implement the <<<ViewPreparer>>>
+  interface. The <<<execute>>> method allows to execute code <<before>> a
+  definition is rendered. You can extend the <<<ViewPreparerSupport>>> class to
+  avoid compiling problems in the case the <<<ViewPreparer>>> interface changes.
+
+----------------------------------------------
+package my.package;
+
+import org.apache.tiles.preparer.PreparerException;
+import org.apache.tiles.preparer.ViewPreparer;
+import org.apache.tiles.request.Request;
+import org.apache.tiles.AttributeContext;
+import org.apache.tiles.Attribute;
+
+public class TestViewPreparer implements ViewPreparer {
+
+    public void execute(Request tilesRequest, AttributeContext attributeContext)
+    throws PreparerException {
+        attributeContext.putAttribute(
+            "body",
+            new Attribute("This is the value added by the ViewPreparer"));
+    }
+}
+----------------------------------------------
+
+* Associating a preparer
+
+  To associate a preparer to a definition, put its complete path name to the
+  <<<preparer>>> attribute of the <<<\<definition\>>>> element:
+
+----------------------------------------------
+<definition name="preparer.definition" preparer="org.apache.tiles.test.preparer.TestViewPreparer">
+  <put-attribute name="foo" value="/bar/foo.jsp" />
+</definition>
+----------------------------------------------
diff --git a/Java-base/tiles/src/src/site/apt/tutorial/advanced/runtime.apt b/Java-base/tiles/src/src/site/apt/tutorial/advanced/runtime.apt
new file mode 100644
index 000000000..4ab8258a4
--- /dev/null
+++ b/Java-base/tiles/src/src/site/apt/tutorial/advanced/runtime.apt
@@ -0,0 +1,127 @@
+~~ $Id$
+~~
+~~ 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.
+~~
+         -----------
+         Tiles Runtime Composition
+         -----------
+
+Tiles Runtime Composition
+
+  Tiles allows to create statically-determined page structures, like we've seen
+  in {{{../basic/pages.html}Creating Pages}}. But Tiles allows to fill
+  templates, modify definitions and create new definitions during the execution.
+
+Runtime Composition in JSP pages
+
+  Making runtime changes in JSP pages is pretty simple. You can use special JSP
+  tags that allow to create page structures on-the-fly.
+
+* Inserting templates
+
+  You can insert a template directly inside a JSP page, filling its attributes
+  at runtime. To do it, you can use the <<<\<tiles:insertTemplate\>>>> tag. The
+  attributes can be put using <<<\<tiles:putAttribute\>>>> and related tags.
+
+  Notice that you have all the features present in XML definition files, such as
+  {{{./nesting-extending.html#Anonymous_nested_definitions}anonymous nested definitions}}
+  and {{{./nesting-extending.html#Cascaded_attributes}cascade attributes}}.
+
+-----------------------------------
+<tiles:insertTemplate template="/layouts/classic.jsp">
+  <tiles:putAttribute name="title" value="Tiles tutorial homepage" />
+  <tiles:putAttribute name="header" value="/tiles/banner.jsp" />
+  <tiles:putAttribute name="menu" value="/tiles/common_menu.jsp" />
+  <tiles:putAttribute name="body">
+    <tiles:insertTemplate template="/layouts/variable_rows.jsp">
+      <tiles:putListAttribute name="items">
+        <tiles:addAttribute value="/tiles/banner.jsp" />
+        <tiles:addAttribute value="/tiles/common_menu.jsp" />
+        <tiles:addAttribute value="/tiles/credits.jsp" />
+      </tiles:putListAttribute>
+    </tiles:insertTemplate>
+  </tiles:putAttribute
+  <tiles:putAttribute name="footer" value="/tiles/credits.jsp" />
+</tiles:insertTemplate>
+-----------------------------------
+
+* {Inserting modified definitions}
+
+  Definitions can be inserted not only just as they are, but also overriding
+  their attributes and their template at runtime:
+
+------------------------------------
+<tiles:insertDefinition name="myapp.homepage.customer" template="/layouts/alternative_layout.jsp">
+  <tiles:putAttribute name="menu" value="/tiles/common_menu_for_customers.jsp" />
+</tiles:insertDefinition>
+------------------------------------
+
+* Creating Definitions
+
+  To create definitions at runtime, first of all you need to configure your
+  Tiles-based application to use a
+  {{{../../config-reference.html#Feature-Complete_configuration}mutable container}}.
+
+  In your JSP page, now you can create definitions. This definition will be
+  available during the request, and then it will expire.
+
+-----------------------------------------
+<tiles:definition name="myapp.homepage.customer" extends="myapp.homepage">
+  <tiles:putAttribute name="menu" value="/tiles/common_menu_for_customers.jsp" />
+</tiles:definition>
+<tiles:insertDefinition name="myapp.homepage.customer" />
+-----------------------------------------
+
+Runtime Composition using APIs
+
+  If you want to compose pages using the Tiles APIs, for example in a servlet
+  environment, you can use the <<container>> feature of Tiles. Essentially Tiles
+  is a container that stores definitions, allow to render pages and allows to
+  modify the configuration at runtime.
+
+* Using the Tiles container
+
+  To get the current container (in a servlet environment) you can use the
+  <<TilesAccess>> class:
+
+-------------------------------------
+TilesContainer container = TilesAccess.getContainer(
+        request.getSession().getServletContext());
+Request tilesRequest = new ServletRequest(container.getApplicationContext(), request, response);
+container.render("myapp.homepage", tilesRequest);
+-------------------------------------
+
+  <<Warning!>> The direct use of <<<AttributeContext>>> is deprecated. The same purpose can be
+  achieved easier and in a more maintainable way using {{{./el-support.html}Expression Languages}}
+
+* Creating Definitions
+
+  To create definitions at runtime, first of all you need to configure your
+  Tiles-based application to use a
+  {{{../../config-reference.html#Feature-Complete_configuration}mutable container}}.
+
+  This is a snippet to show how to create a definition.
+
+-------------------------------------
+MutableTilesContainer container = TilesAccess.getContainer(
+        request.getSession().getServletContext());
+Definition definition = new Definition();
+definition.setTemplate("/layouts/my_layout.jsp");
+definition.putAttribute("body", new Attribute("/tiles/body.jsp");
+container.register(definition, request, response);
+-------------------------------------
diff --git a/Java-base/tiles/src/src/site/apt/tutorial/advanced/security.apt b/Java-base/tiles/src/src/site/apt/tutorial/advanced/security.apt
new file mode 100644
index 000000000..0b610d64e
--- /dev/null
+++ b/Java-base/tiles/src/src/site/apt/tutorial/advanced/security.apt
@@ -0,0 +1,91 @@
+~~ $Id$
+~~
+~~ 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.
+~~
+         -----------
+         Security
+         -----------
+
+Security
+
+  Tiles allows the visibility of a template, an attribute or a definition only
+  to selected roles.
+
+* Allowing definitions
+
+  A definition can be allowed to be rendered only by selected roles:
+
+  * in XML definition files:
+
+---------------------------------
+<definition name="test.definition"
+    template="/layout/my-template.jsp role="myrole">
+    ...
+</definition>
+---------------------------------
+
+  * in JSP pages, when inserting definitions:
+
+---------------------------------
+<tiles:insertDefinition name="test.definition" role="myrole" />
+---------------------------------
+
+  * in JSP pages, when definining definitions:
+
+---------------------------------
+<tiles:definition name="test.definition"
+    template="/layout/my-template.jsp" role="myrole">
+    ...
+</tiles:definition>
+---------------------------------
+
+* Allowing attributes
+
+  An attribute can be allowed to be rendered only by selected roles:
+
+  * in XML definition files:
+
+---------------------------------
+<definition name="test.definition"
+    template="/layout/my-template.jsp>
+  <put-attribute name="header" value="/header.jsp" role="myrole" />
+</definition>
+---------------------------------
+
+  * in JSP pages, when inserting attributes:
+
+---------------------------------
+<tiles:insertAttribute name="header" role="myrole" />
+---------------------------------
+
+  * in JSP pages, when putting attributes:
+
+---------------------------------
+<tiles:putAttribute name="header" value="/header.jsp" role="myrole" />
+---------------------------------
+
+* Allowing templates
+
+  Templates can be allowed to be rendered only by selected rows in JSP pages:
+
+---------------------------------
+<tiles:insertTemplate name="test.definition"
+    template="/layout/my-template.jsp" "role="myrole">
+    ...
+</tiles:insertTemplate>
+---------------------------------
diff --git a/Java-base/tiles/src/src/site/apt/tutorial/advanced/utils.apt b/Java-base/tiles/src/src/site/apt/tutorial/advanced/utils.apt
new file mode 100644
index 000000000..3d3b2445a
--- /dev/null
+++ b/Java-base/tiles/src/src/site/apt/tutorial/advanced/utils.apt
@@ -0,0 +1,82 @@
+~~ $Id$
+~~
+~~ 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.
+~~
+         -----------
+         Rendering Utilities
+         -----------
+
+Tiles Rendering Utilities
+
+  The core package of Tiles contains utilities to render Tiles definitions
+  without the need of a JSP page or a supporting framework.
+
+* <<<TilesDispatchServlet>>>
+
+  The <<<TilesDispatchServlet>>> is a servlet that intercepts the URLs ending
+  with "<<<.tiles>>>" and render the definition whose name is the path name
+  before the "<<<.tiles>>>" part.
+  
+  For example, if you call the <<<testdispatchservlet.tiles>>> path, the
+  rendered definition will be <<<testdispatchservlet>>>.
+
+  You can configure the <<<TilesDispatchServlet>>> this way:
+
+------------------------------------
+<servlet>
+    <servlet-name>Tiles Dispatch Servlet</servlet-name>
+    <servlet-class>org.apache.tiles.web.util.TilesDispatchServlet</servlet-class>
+</servlet>
+...
+<servlet-mapping>
+    <servlet-name>Tiles Dispatch Servlet</servlet-name>
+    <url-pattern>*.tiles</url-pattern>
+</servlet-mapping>
+------------------------------------
+
+  By using the <<<org.apache.tiles.web.util.TilesDispatchServlet.CONTAINER_KEY>>>
+  you can use a different container. The value of this parameter will be used
+  as the key under which the container is stored.
+
+* <<<TilesDecorationFilter>>>
+
+  You can use the <<<TilesDecorationFilter>>> to use Tiles as a <decorator>
+  framework. All the requests intercepted by the filter will be put inside the
+  configured attribute of the configured definition, and then that definition is
+  rendered.
+  
+  You can configure the filter this way:
+
+------------------------------------
+<filter>
+    <filter-name>Tiles Decoration Filter</filter-name>
+    <filter-class>org.apache.tiles.web.util.TilesDecorationFilter</filter-class>
+    <init-param>
+        <param-name>definition</param-name>
+        <param-value>test.definition</param-value>
+    </init-param>
+    <init-param>
+        <param-name>attribute-name</param-name>
+        <param-value>body</param-value>
+    </init-param>
+</filter>
+------------------------------------
+
+  By using the <<<org.apache.tiles.web.util.TilesDecorationFilter.CONTAINER_KEY>>>
+  you can use a different container. The value of this parameter will be used
+  as the key under which the container is stored.
diff --git a/Java-base/tiles/src/src/site/apt/tutorial/advanced/wildcard.apt b/Java-base/tiles/src/src/site/apt/tutorial/advanced/wildcard.apt
new file mode 100644
index 000000000..6a716b0c2
--- /dev/null
+++ b/Java-base/tiles/src/src/site/apt/tutorial/advanced/wildcard.apt
@@ -0,0 +1,169 @@
+~~ $Id$
+~~
+~~ 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.
+~~
+         -----------
+         Wildcard support
+         -----------
+
+Wildcard support
+
+  By default, Tiles supports wildcards in definition names. Wilcards help a
+  lot in writing less code to declare your definitions.
+
+* Default configuration
+
+  Note: default configuration only works if you do not use <<<CompleteAutoloadTilesContainerFactory>>>. If you are using this setting, you can move to the next section.
+
+  Let us start with a simple example. When not using wildcards, you might end up with such tiles definitions:
+
+-----------------------------------
+<definition name="bank/user" template="/layout.jsp">
+    <put-attribute name="header" value="/header.jsp"/>
+    <put-attribute name="body"   value="/user.jsp"/>
+</definition>
+
+<definition name="bank/account" template="/layout.jsp">
+    <put-attribute name="header" value="/header.jsp"/>
+    <put-attribute name="body"   value="/account.jsp"/>
+</definition>
+
+<definition name="bank/customer" template="/layout.jsp">
+    <put-attribute name="header" value="/header.jsp"/>
+    <put-attribute name="body"   value="/customer.jsp"/>
+</definition>
+------------------------------------
+
+  The above definitions are pretty verbose as you need to create one definition per JSP that you're adding to your          application.
+  You could use definition inheritance to reduce the number of lines but you would still need one definition per JSP.
+
+
+** Single star '\*'
+
+  Let's see how to improve that using wildcards. You would then have:
+
+------------------------------------
+<definition name="bank/*" template="/layout.jsp">
+    <put-attribute name="header" value="/header.jsp"/>
+    <put-attribute name="body"   value="/{1}.jsp"/>
+</definition>
+
+------------------------------------
+  Calling a view named "bank/user" matches the above definition name. Inside the "body" attributes, \{1\} refers to the star's value which is "user" in that case.
+
+
+** Multiple stars such as in '\*/\*'
+
+  Let's now consider another case. As you can see, the sample below uses 2 stars '\*'.
+
+------------------------------------
+<definition name="bank/*/*" template="/layout.jsp">
+    <put-attribute name="header" value="/header.jsp"/>
+    <put-attribute name="body"   value="/{1}-{2}.jsp"/>
+</definition>
+
+------------------------------------
+
+  Calling a view named "/bank/customer/account" matches the above definition name.
+  Inside the 'body' attribute, \{1\} refers to the first star and \{2\} refers to the second one.
+  The "body" JSP name will be "customer-account.jsp".
+
+  Here is another example which shows that you can use package-style definition names:
+
+------------------------------------
+<definition name="test.definition*.message*" template="/layout{1}.jsp">
+    <put-attribute name="title"  value="This definition has a message: {2}."/>
+    <put-attribute name="header" value="/header.jsp"/>
+    <put-attribute name="body"   value="/body.jsp"/>
+</definition>
+------------------------------------
+
+
+* Using prefixes
+
+** Enabling CompleteAutoloadTilesContainerFactory
+
+  As a prerequisite for using prefixes, you need to have CompleteAutoloadTilesContainerFactory enabled.
+
+  If you haven't enabled it yet, here is a quick checklist for you to use.
+
+  The library tiles-extras is required. If you're using Maven, you need to add this dependency to you POM file:
+
+
+------------------------------------
+<dependency>
+	<groupId>org.apache.tiles</groupId>
+	<artifactId>tiles-extras</artifactId>
+	<version>3.0.1</version>
+</dependency>
+------------------------------------
+
+	If you are using Spring, you should add the 'completeAutoload' attribute to your TilesConfigurer bean.
+
+------------------------------------
+<bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
+	<property name="completeAutoload" value="true"/>
+</bean>
+------------------------------------
+
+** Using prefixes
+
+	Here is an example of prefix using Regular Expressions:
+
+------------------------------------
+<definition name="REGEXP:test\.definition(.*)\.message(.*)" template="/layout{1}.jsp">
+    <put-attribute name="title"  value="This definition has a message: {2}."/>
+    <put-attribute name="header" value="/header.jsp"/>
+    <put-attribute name="body"   value="/body.jsp"/>
+</definition>
+------------------------------------
+
+	The below sample uses WILDCARD (this prefix is not needed when using wildcards solely, as shown in the 'Default 	Configuration' section).
+
+------------------------------------
+<definition name="WILDCARD:test.definition*.message*" template="/layout{1}.jsp">
+    <put-attribute name="title"  value="This definition has a message: {2}."/>
+    <put-attribute name="header" value="/header.jsp"/>
+    <put-attribute name="body"   value="/body.jsp"/>
+</definition>
+
+<definition name="WILDCARD:bank/*" template="/layout.jsp">
+    <put-attribute name="header" value="/header.jsp"/>
+    <put-attribute name="body"   value="/{1}.jsp"/>
+</definition>
+------------------------------------
+
+
+* tiles:insertDefinition
+
+  In both cases, if you insert a definition that matches the definition, for example:
+
+------------------------------------
+<tiles:insertDefinition name="test.definitionOne.messageThisIsAMessage" />
+------------------------------------
+
+  The definition is automatically mapped, replacing placeholders, marked by
+  curly brackets, with the value of matched definitions. In this case:
+
+------------------------------------
+<definition name="test.definitionOne.messageThisIsAMessage" template="/layoutOne.jsp">
+    <put-attribute name="title"  value="This definition has a message: ThisIsAMessage."/>
+    <put-attribute name="header" value="/header.jsp"/>
+    <put-attribute name="body"   value="/body.jsp"/>
+</definition>
+------------------------------------
\ No newline at end of file
diff --git a/Java-base/tiles/src/src/site/apt/tutorial/basic/concepts.apt b/Java-base/tiles/src/src/site/apt/tutorial/basic/concepts.apt
new file mode 100644
index 000000000..654d61eed
--- /dev/null
+++ b/Java-base/tiles/src/src/site/apt/tutorial/basic/concepts.apt
@@ -0,0 +1,123 @@
+~~ $Id$
+~~
+~~ 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.
+~~
+         -----------
+         Tiles Concepts
+         -----------
+
+Tiles concepts
+
+  Tiles is an implementation of the {{{../pattern.html}Composite View pattern}}.
+  Tiles adds to this pattern its own concepts to make the pattern concrete. The
+  implementation of Tiles around the <Composite View> pattern consists of the
+  {{{./concepts.html#Template}Template}}, {{{./concepts.html#Attribute}Attribute}}
+  and {{{./concepts.html#Definition}Definition}} concepts. The <View Helper>
+  pattern is implemented by the {{{./concepts.html#View Preparer}View Preparer}}
+  concept. 
+
+* {Template}
+
+  In Tiles, a <<template>> is the layout part of a page. You can see as a page
+  structure with some gaps, called <<attributes>>, to be filled.
+  
+  For instance, consider the "classic layout" page structure.
+
+[../../images/tiled_page.png] The "classic layout", a typical structure of a web
+page.
+
+  You can replicate this structure by creating a JSP page, as you can see below.
+
+-------------------------------
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+<table>
+  <tr>
+    <td colspan="2">
+      <tiles:insertAttribute name="header" />
+    </td>
+  </tr>
+  <tr>
+    <td>
+      <tiles:insertAttribute name="menu" />
+    </td>
+    <td>
+      <tiles:insertAttribute name="body" />
+    </td>
+  </tr>
+  <tr>
+    <td colspan="2">
+      <tiles:insertAttribute name="footer" />
+    </td>
+  </tr>
+</table>
+-------------------------------
+  
+  Notice that a template <<can have no attributes>>: in this case it can be used
+  directly.
+
+* {Attribute}
+
+  An <<attribute>> is a gap in a template that needs to be filled in your
+  application. An attribute can be of three types:
+  
+  * <<string>>: it is a string to be directly rendered as it is.
+  
+  * <<template>>: it is a template, with or without attributes. If it has
+  attributes, you have to fill them too to render a page.
+  
+  * <<definition>>: it is a reusable composed page, with all (or some)
+  attributes filled (see below).
+
+* {Definition}
+
+  A <<definition>> is a composition to be rendered to the end user; essentially
+  a definition is composed of a <<template>> and completely or partially
+  <<filled attributes>>.
+  
+  * If <<all>> of its attributes are filled, it can be rendered to the end user.
+  
+  * If <<not all>> of its attributes are filled, it is called an <<abstract
+  definition>>, and it can be used as a base definition for extended
+  definitions, or their missing attributes can be filled at runtime.
+  
+  []
+  
+  For example, you can create a page using the <classic layout> as seen before,
+  by modifying the {{{./pages.html}Tiles configuration file}}.
+  
+------------------------------------
+<definition name="myapp.homepage" template="/layouts/classic.jsp">
+  <put-attribute name="header" value="/tiles/banner.jsp" />
+  <put-attribute name="menu" value="/tiles/common_menu.jsp" />
+  <put-attribute name="body" value="/tiles/home_body.jsp" />
+  <put-attribute name="footer" value="/tiles/credits.jsp" />
+</definition>
+------------------------------------
+
+* {View Preparer}
+
+  Sometimes a definition, before it is rendered, needs to be "prepared". For
+  example when showing a menu, the menu structure must be created and stored
+  in the request scope.
+  
+  For this reason, a <<View Preparer>> can be used: it is called <<before>> the
+  definition is rendered, so all the things needed to render correctly the
+  definition can be prepared.
+  
+  See the {{{../advanced/preparer.html}Tiles View Preparer configuration}} for
+  more information.
diff --git a/Java-base/tiles/src/src/site/apt/tutorial/basic/index.apt b/Java-base/tiles/src/src/site/apt/tutorial/basic/index.apt
new file mode 100644
index 000000000..b8a4e919a
--- /dev/null
+++ b/Java-base/tiles/src/src/site/apt/tutorial/basic/index.apt
@@ -0,0 +1,32 @@
+~~ $Id$
+~~
+~~ 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.
+~~
+         -----------
+         Tiles Basic Usage
+         -----------
+
+Tiles Basic Usage
+
+  In this part of the tutorial, you will learn the basics of Tiles and its
+  simple usage in the most common cases.
+  
+  * {{{./concepts.html}Tiles concepts}}.
+  
+  * {{{./pages.html}Building Tiles-enabled pages}}.
+
diff --git a/Java-base/tiles/src/src/site/apt/tutorial/basic/pages.apt b/Java-base/tiles/src/src/site/apt/tutorial/basic/pages.apt
new file mode 100644
index 000000000..6afc4c8cd
--- /dev/null
+++ b/Java-base/tiles/src/src/site/apt/tutorial/basic/pages.apt
@@ -0,0 +1,134 @@
+~~ $Id$
+~~
+~~ 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.
+~~
+         -----------
+         Creating Tiles Pages
+         -----------
+
+Creating and using Tiles pages
+
+  After installing and learning some of Tiles concepts, it is time to create
+  some pages. Here you will find the steps to create reusable Tiles pieces and
+  complete pages.
+
+* Create a template
+
+  Let's take the <<classic layout>> page structure:
+
+[../../images/tiled_page.png] The "classic layout", a typical structure of a web
+page.
+
+  Create a JSP page that acts as this layout and place it under
+  <<</layouts/classic.jsp>>> file.
+
+-------------------------------
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+<html>
+  <head>
+    <title><tiles:getAsString name="title"/></title>
+  </head>
+  <body>
+	<table>
+      <tr>
+        <td colspan="2">
+          <tiles:insertAttribute name="header" />
+        </td>
+      </tr>
+      <tr>
+        <td>
+          <tiles:insertAttribute name="menu" />
+        </td>
+        <td>
+          <tiles:insertAttribute name="body" />
+        </td>
+      </tr>
+      <tr>
+        <td colspan="2">
+          <tiles:insertAttribute name="footer" />
+        </td>
+      </tr>
+    </table>
+  </body>
+</html>
+-------------------------------
+
+  This template has five attributes: <<<title>>> (of <<<string>>> type),
+  <<<header>>>, <<<menu>>>, <<<body>>> and <<<footer>>>.
+
+* Create the composing pages
+
+  In this phase, you have to create four JSP pages, that will take place of
+  <<<header>>>, <<<menu>>>, <<<body>>> and <<<footer>>> attributes in the
+  previously created template.
+
+  You can put everything you want in this pages, they are just a test.
+
+* Create a definition
+
+  By default, the definition file is <<</WEB-INF/tiles.xml>>>. If you're using <<<CompleteAutoloadTilesListener>>>,
+  tiles will use any file in the webapp that matches <<</WEB-INF/tiles*.xml>>> or any file in the classpath that matches
+  <<</META-INF/tiles*.xml>>>; if several are found, it will merge them together.  
+  
+  But for now, let's stick to the default and create the <<</WEB-INF/tiles.xml>>> file, with a definition
+  as described in {{{./concepts.html}concepts}}:
+
+------------------------------------
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"
+       "http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
+<tiles-definitions>
+  <definition name="myapp.homepage" template="/layouts/classic.jsp">
+    <put-attribute name="title" value="Tiles tutorial homepage" />
+    <put-attribute name="header" value="/tiles/banner.jsp" />
+    <put-attribute name="menu" value="/tiles/common_menu.jsp" />
+    <put-attribute name="body" value="/tiles/home_body.jsp" />
+    <put-attribute name="footer" value="/tiles/credits.jsp" />
+  </definition>
+</tiles-definitions>
+------------------------------------
+
+* Render the definition
+
+  After creating the definition, you can render it:
+
+  * by using the <<<\<tiles:insertDefinition /\>>>> tag, inserting it in a JSP
+  page:
+
+-------------------------------------
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+<tiles:insertDefinition name="myapp.homepage" />
+-------------------------------------
+
+  * in other cases, you can render directly in the response, by using the Tiles
+  container:
+
+-----------------------------------
+TilesContainer container = TilesAccess.getContainer(
+        request.getSession().getServletContext());
+container.render("myapp.homepage", request, response);
+-----------------------------------
+
+  * by using {{{../advanced/utils.html}Rendering Utilities}} provided by Tiles. For instance,
+  if you've configured <<<TilesDispatchServlet>>>, you can render the definition above by
+  requesting <<<http://example.com/webapp/myapp.homepage.tiles>>>.
+
+  * by using a supporting framework. See
+  {{{../integration/index.html}Integrations}} for a list of supporting
+  frameworks.
diff --git a/Java-base/tiles/src/src/site/apt/tutorial/configuration.apt b/Java-base/tiles/src/src/site/apt/tutorial/configuration.apt
new file mode 100644
index 000000000..f72a61de0
--- /dev/null
+++ b/Java-base/tiles/src/src/site/apt/tutorial/configuration.apt
@@ -0,0 +1,74 @@
+~~ $Id$
+~~
+~~ 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.
+~~
+         -----------
+         Tiles Configuration
+         -----------
+
+Configuring Tiles in your web application
+
+  Tiles has always been a web application package, usually used in conjunction
+  with Struts. Apache Tiles\u0099 evolved to the point of being technology-independent, but
+  its use in a Servlet-based web application is still the most frequent use case.
+
+* Required libraries
+
+  The first thing is to install the required libraries. For the purpose of this tutorial,
+  we will install everything: the more we can do, the better. Just know that a 
+  more "lightweight" but limited configuration is available.
+  
+  If you're using maven, just include this dependency, it will include the rest:
+  
+-------------
+<groupId>org.apache.tiles</groupId>
+<artifactId>tiles-extras</artifactId>
+-------------  
+  
+  If you're not using maven, just {{{/download.html}download}} tiles and copy all the jars
+  into the /WEB-INF/lib directory.
+
+* Starting Tiles engine
+
+  Load the tiles container by using the appropriate listener it in your <<<web.xml>>> file. Since we
+  decided to load everything, we'll use <<<CompleteAutoloadTilesListener>>>:
+
+-------------------------------
+<listener>
+    <listener-class>org.apache.tiles.extras.complete.CompleteAutoloadTilesListener</listener-class>
+</listener>
+-------------------------------
+
+  For this tutorial, we'll configure Tiles to work directly with the servlet API, without a controller.
+  In the real world, you'll probably use an MVC framework like Struts or Shale or Spring. You have to 
+  configure your framework to work with Tiles; please refer to your framework's documentation for that. 
+  For now, we'll just declare <<<TilesDispatchServlet>>> in <<<web.xml>>>:
+  
+-------------------------------
+<servlet>
+    <servlet-name>Tiles Dispatch Servlet</servlet-name>
+    <servlet-class>org.apache.tiles.web.util.TilesDispatchServlet</servlet-class>
+</servlet>
+<servlet-mapping>
+    <servlet-name>Tiles Dispatch Servlet</servlet-name>
+    <url-pattern>*.tiles</url-pattern>
+</servlet-mapping>
+-------------------------------
+
+  This means that any request to an URL ending in ".tiles" will be dispatched directly to the matching
+  Tiles Definition.
diff --git a/Java-base/tiles/src/src/site/apt/tutorial/index.apt b/Java-base/tiles/src/src/site/apt/tutorial/index.apt
new file mode 100644
index 000000000..fb0262c61
--- /dev/null
+++ b/Java-base/tiles/src/src/site/apt/tutorial/index.apt
@@ -0,0 +1,68 @@
+~~ $Id$
+~~
+~~ 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.
+~~
+         -----------
+         Tutorial
+         -----------
+
+Introduction
+
+  This tutorial is intended to provide a help for first-time Tiles users, in the context of a web application.
+
+Summary
+
+  [[1]] {{{./pattern.html}The "composite view" pattern}}
+
+  [[2]] {{{./configuration.html}Configuring your web application}}
+
+  [[3]] {{{./basic/index.html}Basic Usage}}
+
+        [[1]] {{{./basic/concepts.html}Tiles Concepts}}
+
+        [[2]] {{{./basic/pages.html}Creating Tiles Pages}}
+
+  [[4]] {{{./advanced/index.html}Advanced Topics}}
+
+        [[1]] {{{./advanced/nesting-extending.html}Nesting and Extending Definitions}}
+
+        [[2]] {{{./advanced/list-attributes.html}List Attributes}}
+
+        [[3]] {{{./advanced/runtime.html}Runtime Composition}}
+
+        [[4]] {{{./advanced/preparer.html}View Preparers}}
+
+        [[5]] {{{./advanced/utils.html}Rendering Utilities}}
+
+        [[6]] {{{./advanced/l10n.html}Tiles Localization}}
+
+        [[7]] {{{./advanced/wildcard.html}Wildcard support}}
+
+        [[8]] {{{./advanced/el-support.html}EL support}}
+
+        [[8]] {{{./advanced/attribute-rendering.html}Attribute rendering}}
+
+        [[9]] {{{./advanced/multiple-containers.html}Using multiple containers}}
+
+        [[10]] {{{./advanced/security.html}Security}}
+
+  [[5]] {{{./integration/index.html}Integration with other technologies}}
+
+        [[1]] {{{./integration/frameworks.html}Integration with other frameworks}}
+
+        [[2]] {{{./integration/view.html}Integration with other view technologies}}
diff --git a/Java-base/tiles/src/src/site/apt/tutorial/integration/frameworks.apt b/Java-base/tiles/src/src/site/apt/tutorial/integration/frameworks.apt
new file mode 100644
index 000000000..60867a0ef
--- /dev/null
+++ b/Java-base/tiles/src/src/site/apt/tutorial/integration/frameworks.apt
@@ -0,0 +1,43 @@
+~~ $Id$
+~~
+~~ 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.
+~~
+         -----------
+         Integration with other Frameworks
+         -----------
+
+Integration with other web Frameworks
+
+  Tiles can be integrated with other web frameworks. Usually this kind of
+  integration is made through extensions/plugins to Tiles.
+
+  * {{{http://struts.apache.org/1.x/index.html}Struts 1}}: Currently under
+  development. A Struts 1 plugin is available in the SVN trunk, that presumably
+  will be released along with Struts 1.4.
+
+  * {{{http://struts.apache.org/development/2.x/struts2-plugins/struts2-tiles-plugin/apidocs/index.html}Struts 2}}: at the time of this
+  writing, the Struts 2 Tiles plugin still uses Tiles version 2.
+
+  * {{{http://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/view.html#view-tiles}Spring MVC}}:
+  Spring-3.2 can integration up to Tiles-2 and Tiles-3.
+
+
+
+  For a closer look at custom integrations the
+  {{{https://github.com/spring-projects/spring-framework/tree/master/spring-webmvc-tiles3/src/main/java/org/springframework/web/servlet/view/tiles3}spring code}}:
+  forms a good example.
diff --git a/Java-base/tiles/src/src/site/apt/tutorial/integration/freemarker.apt b/Java-base/tiles/src/src/site/apt/tutorial/integration/freemarker.apt
new file mode 100644
index 000000000..0e6b974f6
--- /dev/null
+++ b/Java-base/tiles/src/src/site/apt/tutorial/integration/freemarker.apt
@@ -0,0 +1,121 @@
+~~ $Id$
+~~
+~~ 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.
+~~
+         -----------
+         Integration with FreeMarker
+         -----------
+
+Integration with FreeMarker
+
+  {{{http://freemarker.sourceforge.net/}FreeMarker}} is a templating framework
+  that can be used as a replacement for JavaServer Pages (JSP). Tiles can be
+  used with FreeMarker through the use of Tiles FreeMarker package.
+
+* Configuration
+
+  To use FreeMarker together with Tiles
+
+  * Add FreeMarker jars (tested with FreeMarker 2.3.15).
+
+  * Add <<<tiles-template-x.x.x.jar>>> and <<<tiles-freemarker-x.x.x.jar>>> files
+  to your application
+
+  * To access ".ftl" files from HTTP requests, add this piece of configuration in <<<web.xml>>>
+  (the parameters can be modified as needed).
+
+----------------------------------
+<servlet>
+    <servlet-name>freemarker</servlet-name>
+    <servlet-class>org.apache.tiles.freemarker.servlet.TilesFreemarkerServlet</servlet-class>
+
+    <!-- FreemarkerServlet settings: -->
+    <init-param>
+        <param-name>TemplatePath</param-name>
+        <param-value>/</param-value>
+    </init-param>
+    <init-param>
+        <param-name>NoCache</param-name>
+        <param-value>true</param-value>
+    </init-param>
+    <init-param>
+        <param-name>ContentType</param-name>
+        <param-value>text/html</param-value>
+    </init-param>
+
+    <!-- FreeMarker settings: -->
+    <init-param>
+        <param-name>template_update_delay</param-name>
+        <param-value>0</param-value> <!-- 0 is for development only! Use higher value otherwise. -->
+    </init-param>
+    <init-param>
+        <param-name>default_encoding</param-name>
+        <param-value>ISO-8859-1</param-value>
+    </init-param>
+    <init-param>
+        <param-name>number_format</param-name>
+        <param-value>0.##########</param-value>
+    </init-param>
+
+    <load-on-startup>5</load-on-startup>
+</servlet>
+----------------------------------
+
+  * To access ".ftl" files as attributes, register FreeMarkerAttributeRenderer
+  this way (only available in a servlet environment):
+
+----------------------------------
+@Override
+protected void registerAttributeRenderers(
+        BasicRendererFactory rendererFactory, TilesApplicationContext applicationContext,
+        TilesRequestContextFactory contextFactory,
+        TilesContainer container, AttributeEvaluator evaluator) {
+    super.registerAttributeRenderers(rendererFactory, applicationContext, contextFactory,
+            container, evaluator);
+    FreeMarkerAttributeRenderer freemarkerRenderer = new FreeMarkerAttributeRenderer();
+    freemarkerRenderer.setApplicationContext(applicationContext);
+    freemarkerRenderer.setEvaluator(evaluator);
+    freemarkerRenderer.setRequestContextFactory(contextFactory);
+    freemarkerRenderer.setParameter("TemplatePath", "/");
+    freemarkerRenderer.setParameter("NoCache", "true");
+    freemarkerRenderer.setParameter("ContentType", "text/html");
+    freemarkerRenderer.setParameter("template_update_delay", "0");
+    freemarkerRenderer.setParameter("default_encoding", "ISO-8859-1");
+    freemarkerRenderer.setParameter("number_format", "0.##########");
+    freemarkerRenderer.commit();
+    rendererFactory.registerRenderer("freemarker", freemarkerRenderer);
+}
+----------------------------------
+
+  This way you can specify an attribute that is rendered directly using this syntax:
+
+----------------------------------
+<put-attribute name="myAttribute" value="/pages/myPage.ftl" type="freemarker" />
+----------------------------------
+
+* Usage in FreeMarker templates
+
+  Tiles directives are available this way:
+
+----------------------------------
+<@tiles.nameOfDirective>
+  Other stuff...
+</@tiles.nameOfDirective>
+----------------------------------
+
+  For details about directives see the {{{../../apidocs/index.html}Javadocs}}.
diff --git a/Java-base/tiles/src/src/site/apt/tutorial/integration/index.apt b/Java-base/tiles/src/src/site/apt/tutorial/integration/index.apt
new file mode 100644
index 000000000..1593ad813
--- /dev/null
+++ b/Java-base/tiles/src/src/site/apt/tutorial/integration/index.apt
@@ -0,0 +1,32 @@
+~~ $Id$
+~~
+~~ 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.
+~~
+         -----------
+         Tiles Integrations
+         -----------
+
+Tiles integrations
+
+  Tiles can be integrated with various frameworks and view technologies, to
+  include Tiles elements into their specific features.
+  
+  * {{{./frameworks.html}Integration in web frameworks}}.
+  
+  * {{{./view.html}Integration in view technologies}}.
+
diff --git a/Java-base/tiles/src/src/site/apt/tutorial/integration/velocity.apt b/Java-base/tiles/src/src/site/apt/tutorial/integration/velocity.apt
new file mode 100644
index 000000000..a5c5529e5
--- /dev/null
+++ b/Java-base/tiles/src/src/site/apt/tutorial/integration/velocity.apt
@@ -0,0 +1,163 @@
+~~ $Id$
+~~
+~~ 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.
+~~
+         -----------
+         Integration with Apache Velocity
+         -----------
+
+Integration with Apache Velocity
+
+  {{{http://velocity.apache.org/}Apache Velocity}} is a templating framework
+  that can be used as a replacement for JavaServer Pages (JSP). Tiles can be
+  used with Velocity through the use of Tiles Velocity package.
+
+* Configuration
+
+  To use Velocity together with Tiles
+
+  * Add Velocity (1.7 or better) and Velocity Tools (2.0 or better) jars to your application.
+
+  * Add <<<tiles-template-x.x.x.jar>>> and <<<tiles-velocity-x.x.x.jar>>> files
+  to your application.
+  * Add this code in you <<<velocity.properties>>> file:
+
+----------------------------------
+userdirective=org.apache.tiles.velocity.template.AddAttributeDirective,\
+  org.apache.tiles.velocity.template.AddListAttributeDirective,\
+  org.apache.tiles.velocity.template.DefinitionDirective,\
+  org.apache.tiles.velocity.template.GetAsStringDirective,\
+  org.apache.tiles.velocity.template.ImportAttributeDirective,\
+  org.apache.tiles.velocity.template.InsertAttributeDirective,\
+  org.apache.tiles.velocity.template.InsertDefinitionDirective,\
+  org.apache.tiles.velocity.template.InsertTemplateDirective,\
+  org.apache.tiles.velocity.template.PutAttributeDirective,\
+  org.apache.tiles.velocity.template.PutListAttributeDirective
+----------------------------------
+
+
+  * To access ".vm" files from HTTP requests, add this piece of configuration in <<<web.xml>>>
+  (the parameters can be modified as needed).
+
+----------------------------------
+<servlet>
+  <servlet-name>velocity</servlet-name>
+  <servlet-class>org.apache.velocity.tools.view.VelocityViewServlet</servlet-class>
+
+  <init-param>
+    <param-name>org.apache.velocity.toolbox</param-name>
+    <param-value>/WEB-INF/tools.xml</param-value>
+  </init-param>
+
+  <init-param>
+    <param-name>org.apache.velocity.properties</param-name>
+    <param-value>/WEB-INF/velocity.properties</param-value>
+  </init-param>
+</servlet>
+----------------------------------
+
+  * To access ".vm" files as attributes, register VelocityAttributeRenderer
+  this way (only available in a servlet environment):
+
+----------------------------------
+@Override
+protected void registerAttributeRenderers(
+        BasicRendererFactory rendererFactory, TilesApplicationContext applicationContext,
+        TilesRequestContextFactory contextFactory,
+        TilesContainer container, AttributeEvaluator evaluator) {
+    super.registerAttributeRenderers(rendererFactory, applicationContext, contextFactory,
+            container, evaluator);
+
+    VelocityAttributeRenderer velocityRenderer = new VelocityAttributeRenderer();
+    velocityRenderer.setApplicationContext(applicationContext);
+    velocityRenderer.setEvaluator(evaluator);
+    velocityRenderer.setRequestContextFactory(contextFactory);
+    velocityRenderer.setParameter("org.apache.velocity.toolbox", "/WEB-INF/tools.xml");
+    velocityRenderer.setParameter("org.apache.velocity.properties", "/WEB-INF/velocity.properties");
+    velocityRenderer.commit();
+    rendererFactory.registerRenderer("velocity", velocityRenderer);
+}
+----------------------------------
+
+  This way you can specify an attribute that is rendered directly using this syntax:
+
+----------------------------------
+<put-attribute name="myAttribute" value="/pages/myPage.vm" type="velocity" />
+----------------------------------
+
+* Usage in Velocity templates
+
+  There are two ways to use Tiles-Velocity integration:
+
+  * the <<<tiles>>> tool, that is a Velocity-style tool:
+
+----------------------------------
+$tilesAlt.startAttributeContext()
+$set($templateAttribute = $tilesAlt.createTemplateAttribute("/page/myTemplate.vm"))
+$set($attributeContext = $tilesAlt.getAttributeContext())
+  $set($attribute = $tilesAlt.createAttribute())
+  $attribute.setValue("This is the title.")
+  $attributeContext.putAttribute("title", $attribute})
+
+  $set($attribute = $tilesAlt.createAttribute())
+  $attribute.setValue("/velocity/header.vm")
+  $attribute.setRenderer("velocity")
+  $attributeContext.putAttribute("header", $attribute})
+
+  $set($attribute = $tilesAlt.createAttribute())
+  $attribute.setValue("/velocity/body.vm")
+  $attribute.setRenderer("velocity")
+  $attributeContext.putAttribute("body", $attribute})
+
+$tilesAlt.render($templateAttribute)
+$tilesAlt.endAttributeContext()
+----------------------------------
+
+  * the <<<tiles>>> directives, that have a tag-like meaning.
+
+----------------------------------
+#tiles_insertTemplate({"template":"/page/myTemplate.vm"})
+  #tiles_putAttribute({"name":"title", "value":"This is the title."})#end
+  #tiles_putAttribute({"name":"header", "value":"/velocity/header.vm", "type":"velocity"})#end
+  #tiles_putAttribute({"name":"body", "value":"/velocity/body.vm", "type":"velocity"})#end
+#end
+----------------------------------
+
+  Other <<<tiles>>> directives are:
+  
+      * <<<getAsString(String attributeName)>>> - get the value of named attribute as string.
+
+      * <<<importAttribute(String attributeName, String toName)>>> - import the named attribute into the scope of
+  	template context under the (optional) custom name.
+
+      * <<<insertAttribute(String attributeName)>>> - inserts given attribute in the output in its own context.
+        If this is a string a string is printed, if this is a definition - it is included in the output.
+
+      * <<<insertAttribute(String attributeName, boolean ownContext)>>> - inserts given attribute in the output.
+        If this is a string a string is printed, if this is a definition - it is included in the output. You can specify whether
+        a separate context is created for rendering the definition - in this case variables with duplicate names
+        will not be inherited from the parent definition
+
+      * <<<insertDefinition(String definitionName)>>> - renders a definition in its own context.
+
+      * <<<insertDefinition(String definitionName, boolean ownContext)>>> - inserts definition, optionally in the shared context.
+
+      * <<<insertTemplate(String template)>>> - inserts a named page, equivalent to Velocity's <<<#parse>>>.
+
+
+  For details about the tool and directives see the {{{../../apidocs/index.html}Javadocs}}.
diff --git a/Java-base/tiles/src/src/site/apt/tutorial/integration/view.apt b/Java-base/tiles/src/src/site/apt/tutorial/integration/view.apt
new file mode 100644
index 000000000..3a02f867d
--- /dev/null
+++ b/Java-base/tiles/src/src/site/apt/tutorial/integration/view.apt
@@ -0,0 +1,33 @@
+~~ $Id$
+~~
+~~ 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.
+~~
+         -----------
+         Integration with other View Technologies
+         -----------
+
+Integration with other View Technologies
+
+  Currently Apache Tiles\u0099 is not only integrated with JavaServer Pages, but it can be used
+  with:
+
+  * {{{./freemarker.html}FreeMarker}}.
+
+  * {{{./velocity.html}Velocity}}.
+
+  * Mustache.
diff --git a/Java-base/tiles/src/src/site/apt/tutorial/pattern.apt b/Java-base/tiles/src/src/site/apt/tutorial/pattern.apt
new file mode 100644
index 000000000..2d39d4de1
--- /dev/null
+++ b/Java-base/tiles/src/src/site/apt/tutorial/pattern.apt
@@ -0,0 +1,109 @@
+~~ $Id$
+~~
+~~ 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.
+~~
+         -----------
+         The Composite View Pattern
+         -----------
+
+The Composite View Pattern
+
+  All websites have something in common: they are made of pages that share
+  similar structures. The pages share the same layout, while each page is made
+  of different independent pieces, but always placed in the same position across
+  all the site.
+
+  The <<Composite View>> pattern formalizes this typical use, by allowing to
+  create pages that have a similar structure, in which each section of the page
+  vary in different situations.
+
+* How the pattern works
+
+  To understand this pattern, let's take an example. In the following picture
+  you can see a typical structure of a web page.
+
+[../images/tiled_page.png] The "classic layout", a typical structure of a web
+page.
+
+  This structure is called "Classic Layout". The template organizes the page
+  according to this layout, putting each "piece" in the needed place, so that
+  the header goes up, the footer down, etc.
+
+  It can happen that, for example clicking on a link, it is needed to change
+  only a part of the page, typically the body.
+
+[../images/page_to_page.png] The body changes, while the rest remains the same.
+
+  As you can see, the pages are different, but their difference is only in the
+  body part. Note that, however, <<the pages are distinct>>, it is not like a
+  refresh of a frame in a frameset!
+  
+  Using the composite view pattern, the other part of the page have been reused,
+  and the layout consistence has been preserved.
+  
+* The role of the View Helper
+
+  Each piece of the composed page can have a "view helper". This pattern allows
+  the preparation of the data to be displayed in a consistent way for the page
+  piece itself, for example to create a menu.
+
+* Composite View vs. Decorator
+
+  Tiles is a composite view framework: it allows to reuse page pieces across
+  the application. But another approach to achieve the same result is using the
+  <<Decorator pattern>>. For example,
+  {{{http://www.sitemesh.org/}Sitemesh}} is based on the Decorator
+  pattern.
+  
+  Instead of creating a template and organizing the pieces together, the
+  Decorator pattern (in this case) takes a simple HTML page, transforms it
+  adding the missing pieces (in our example, adding header, footer and menu) and
+  finally renders it.
+  
+  Here you can find a comparison table between the two patterns.
+  
+*---------------+--------------------------------+-----------------------------+
+| <<Aspect>>    | <<Composite View>>             | <<Decorator>>               |
+*---------------+--------------------------------+-----------------------------+
+| Reusability   | The different parts of the     | Each decorator can be       |
+|               | page (template and pieces) can | reused, but the decoration  |
+|               | be reused across the whole     | itself can be applied to    |
+|               | application.                   | one page at a time.         |
+*---------------+--------------------------------+-----------------------------+
+| Ease of       | Each page must be defined      | The decorator can be        |
+| configuration | explicitly.                    | applied even to the entire  |
+|               |                                | application.                |
+*---------------+--------------------------------+-----------------------------+
+| Runtime       | The pages can be configured    | Since one page is decorated |
+| configuration | and organized at runtime       | at a time, this feature is  |
+|               |                                | not present.                |
+*---------------+--------------------------------+-----------------------------+
+| Performances  | Low overhead for composition.  | The page to be decorated    |
+|               |                                | has to be parsed.           |
+*---------------+--------------------------------+-----------------------------+
+
+
+* References
+
+  You can see the complete description of the Composite View pattern at:
+  
+  * {{{http://java.sun.com/blueprints/corej2eepatterns/Patterns/CompositeView.html}
+  Sun's Core J2EE Patterns}}
+  
+  * {{{http://java.sun.com/blueprints/patterns/CompositeView.html}
+  Sun's Blueprints Patterns}}
diff --git a/Java-base/tiles/src/src/site/apt/whats-new.apt b/Java-base/tiles/src/src/site/apt/whats-new.apt
new file mode 100644
index 000000000..eecc4017e
--- /dev/null
+++ b/Java-base/tiles/src/src/site/apt/whats-new.apt
@@ -0,0 +1,52 @@
+~~ $Id$
+~~
+~~ 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.
+~~
+         -----------
+         What's new in Tiles 3.0
+         -----------
+
+What's new in Tiles 3.0
+
+* New features in Tiles 3.0
+
+  * {{{/tiles-request/}Apache Request}}: a framework independent request abstraction. Implementations for Servlet, 
+  Portlet, JSP, Velocity, FreeMarker and Mustache.
+
+  * {{{/tiles-autotag/}Apache Autotag}}: a tool that automatically generates tags (or tag-like) artifact from a common template code for a range of templating languages.
+  All the Tiles 3 boilerplate code to templating models has been removed and uses the Autotag plugins instead:
+  it's a lot of boilerplate, boring code, now generated automatically.
+
+* Deprecations in Tiles 3.0
+
+  * Starting Tiles in a web environment using a dummy Servlet. Use a ServletContextListener instead.
+  
+  * Don't use the AttributeContext interface to pass attribute values to Tiles. Expression Languages are an easier, more maintainable 
+  way to change the value of attributes on a per-render basis.
+
+  * ...
+
+* Removals in Tiles 3.0
+
+  * Upgraded from JavaSE 5.0 to JavaSE 6.0.
+  
+  * Upgraded from Servlet 2.4 and JSP 2.0 to Servlet 2.5 and JSP 2.1.
+  
+  * Changed the Java API to adopt the Request API. The XML files and taglibs are compatible with tiles 2.2.
+  
+  * Dropped the parameter based configuration that was deprecated in 2.2.
diff --git a/Java-base/tiles/src/src/site/resources/images/page_to_page.png b/Java-base/tiles/src/src/site/resources/images/page_to_page.png
new file mode 100644
index 000000000..78883ad50
Binary files /dev/null and b/Java-base/tiles/src/src/site/resources/images/page_to_page.png differ
diff --git a/Java-base/tiles/src/src/site/resources/images/tiled_page.png b/Java-base/tiles/src/src/site/resources/images/tiled_page.png
new file mode 100644
index 000000000..f8f2ee152
Binary files /dev/null and b/Java-base/tiles/src/src/site/resources/images/tiled_page.png differ
diff --git a/Java-base/tiles/src/src/site/site.xml b/Java-base/tiles/src/src/site/site.xml
new file mode 100644
index 000000000..9cd30e5fe
--- /dev/null
+++ b/Java-base/tiles/src/src/site/site.xml
@@ -0,0 +1,206 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<project name="Apache Tiles - Framework">
+     <skin>
+        <groupId>org.apache.maven.skins</groupId>
+        <artifactId>maven-fluido-skin</artifactId>
+        <version>1.3.0</version>
+     </skin>
+     <custom>
+        <fluidoSkin>
+        <topBarEnabled>true</topBarEnabled>
+        <sideBarEnabled>false</sideBarEnabled>
+        <searchEnabled>true</searchEnabled>
+        <gitHub>
+            <projectId>apache/tiles</projectId>
+            <ribbonOrientation>right</ribbonOrientation>
+            <ribbonColor>darkblue</ribbonColor>
+        </gitHub>
+        </fluidoSkin>
+     </custom>
+    <bannerLeft>
+        <name>Apache Tiles&#8482;</name>
+        <src>http://tiles.apache.org/images/logo.png</src>
+        <href>http://tiles.apache.org</href>
+    </bannerLeft>
+    <bannerRight>
+        <name>Apache Software Foundation</name>
+        <href>http://www.apache.org</href>
+        <src>https://tiles.apache.org/images/logos/asf_logo_url.svg</src>
+    </bannerRight>
+    <body>
+
+        <menu name="Apache Tiles&#8482;">
+            <item
+                   name="Welcome"
+                   href="../index.html"/>
+            <item
+                    name="Tiles 3.0.x"
+                    href="index.html"/>
+            <item
+                    name="Autotag 1.0.x"
+                    href="../tiles-autotag/index.html"/>
+            <item
+                    name="Request 1.0.x"
+                    href="../tiles-request/index.html"/>
+            <item
+                   name="Security bulletins"
+                   href="security/index.html"/>
+        </menu>
+        <menu name="User Documentation">
+            <item
+                    name="What's new"
+                    href="whats-new.html"/>
+            <item
+                    name="Getting Started"
+                    href="getting_started.html"/>
+            <item
+                    name="Tutorial"
+                    href="tutorial/index.html"
+                    collapse="true">
+                <item
+                        name="The composite view pattern"
+                        href="tutorial/pattern.html"/>
+                <item
+                        name="Configuration"
+                        href="tutorial/configuration.html"/>
+                <item
+                        name="Basic Usage"
+                        href="tutorial/basic/index.html"
+                        collapse="true">
+                    <item
+                            name="Tiles Concepts"
+                            href="tutorial/basic/concepts.html"/>
+                    <item
+                            name="Creating Pages"
+                            href="tutorial/basic/pages.html"/>
+                </item>
+                <item
+                        name="Advanced Topics"
+                        href="tutorial/advanced/index.html"
+                        collapse="true">
+                    <item
+                            name="Nesting and Extending"
+                            href="tutorial/advanced/nesting-extending.html"/>
+                    <item
+                            name="List Attributes"
+                            href="tutorial/advanced/list-attributes.html"/>
+                    <item
+                            name="Runtime Composition"
+                            href="tutorial/advanced/runtime.html"/>
+                    <item
+                            name="View Preparers"
+                            href="tutorial/advanced/preparer.html"/>
+                    <item
+                            name="Rendering Utilities"
+                            href="tutorial/advanced/utils.html"/>
+                    <item
+                            name="Localization"
+                            href="tutorial/advanced/l10n.html"/>
+                    <item
+                            name="Wildcard support"
+                            href="tutorial/advanced/wildcard.html"/>
+                    <item
+                            name="EL support"
+                            href="tutorial/advanced/el-support.html"/>
+                    <item
+                            name="Attribute rendering"
+                            href="tutorial/advanced/attribute-rendering.html"/>
+                    <item
+                            name="Multiple containers"
+                            href="tutorial/advanced/multiple-containers.html"/>
+                    <item
+                            name="Security"
+                            href="tutorial/advanced/security.html"/>
+                </item>
+                <item
+                        name="Integrations"
+                        href="tutorial/integration/index.html"
+                        collapse="true">
+                    <item
+                            name="Frameworks"
+                            href="tutorial/integration/frameworks.html"/>
+                    <item
+                            name="View technologies"
+                            href="tutorial/integration/view.html">
+                        <item
+                                name="FreeMarker"
+                                href="tutorial/integration/freemarker.html"/>
+                        <item
+                                name="Velocity"
+                                href="tutorial/integration/velocity.html"/>
+                    </item>
+                </item>
+            </item>
+            <item
+                    name="Wiki"
+                    href="http://cwiki.apache.org/TILES/"/>
+            <item
+                    name="Struts Migration"
+                    href="migration/index.html"/>
+        </menu>
+        <menu name="Reference">
+            <item
+                    name="Configuration reference"
+                    href="config-reference.html"/>
+            <item
+                    name="Javadoc"
+                    href="apidocs/index.html"/>
+            <item
+                    name="Taglibdoc"
+                    href="tiles-jsp/tlddoc/index.html"/>
+            <item
+                    name="Taglib Reference"
+                    href="tiles-jsp/tagreference.html"/>
+            <item
+                    name="DTD Doc"
+                    href="tiles-core/dtddoc/index.html"/>
+        </menu>
+
+        <menu name="Developers">
+            <item
+                    name="Building"
+                    href="dev/building.html"/>
+            <item
+                    name="Snapshots"
+                    href="dev/snapshots.html"/>
+            <item
+                    name="Release Process"
+                    href="dev/release.html"/>
+            <item
+                    name="Selenium Testing"
+                    href="selenium.html"/>
+        </menu>
+
+        <menu ref="modules" />
+        <menu ref="reports" />
+
+        <footer>
+            <div class="row span12">
+                Apache Tiles, Tiles, Apache, the Apache feather logo, and the Apache Tiles
+                project logos are trademarks of The Apache Software Foundation.
+            </div>
+        </footer>
+    </body>
+</project>
diff --git a/Java-base/tiles/src/src/site/xdoc/dev/building.xml b/Java-base/tiles/src/src/site/xdoc/dev/building.xml
new file mode 100644
index 000000000..7fb099a03
--- /dev/null
+++ b/Java-base/tiles/src/src/site/xdoc/dev/building.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0"?>
+<!--
+/*
+ * $Id$
+ *
+ * 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>Apache Tiles</title>
+    </properties>
+
+    <body>
+        <section name="Building Tiles">
+          <subsection name="Prerequisites">
+            <p>For all the next instructions, we assume that you downloaded and
+            installed <a href="http://maven.apache.org/">Maven</a>.</p>
+            <p>To download packages from the source repository, you need to
+            download and install <a href="http://subversion.tigris.org/">
+            Subversion</a>.</p>
+            <p>If you want to build something including JavaDocs (assemblies,
+            sites and JavaDoc report itself) you need to install
+            <a href="http://www.graphviz.org/">GraphViz</a>, otherwise you will
+            notice missing pictures inside JavaDocs pages.</p>
+          </subsection>
+          <subsection name="Building main packages">
+            <p>To build Tiles from source you need to:</p>
+            <ul>
+            <li><p><a href="/download.html">download</a> the source
+            distribution, or checkout the latest version:</p>
+            <p><source>svn co http://svn.apache.org/repos/asf/tiles/framework/trunk/tiles-parent</source></p></li>
+            <li><p>go into the source directory and type:</p>
+            <p><source>mvn package</source></p></li>
+            </ul>
+            <p>You will find the generated JARs under:</p>
+            <ul>
+            <li>{tiles-dir}/tiles-{module}/target/tiles-{module}-${version}.jar</li>
+            </ul>
+          </subsection>
+          <subsection name="Building Tiles Test webapp">
+            <p>See <a href="../selenium.html">Selenium testing with Tiles Test
+            webapp</a>.</p>
+          </subsection>
+          <subsection name="Building distributions">
+            <p>To build distributions, you need to:</p>
+            <ul>
+            <li><p><a href="/download.html">download</a> the source
+            distribution, or checkout the latest version:</p>
+            <p><source>svn co http://svn.apache.org/repos/asf/tiles/framework/trunk/</source></p></li>
+            <li><p>go into the source directory and type:</p>
+            <p><source>mvn install site</source></p></li>
+            <li><p>go into the <code>{tiles-dir}/assembly</code> directory and
+            type:</p>
+            <p><source>mvn assembly:assembly</source></p></li>
+            </ul>
+            <p>You will find the generated distribution under
+            <code>{tiles-dir}/assembly/target/assembly/out</code>.</p>
+          </subsection>
+        </section>
+        <section name="Building Tiles websites">
+          <p>There are four Tiles websites: the main website and the projects
+          websitesi (tiles-request, tiles-autotag, framework).</p>
+          <subsection name="Building main website">
+            <p>To build the main website:</p>
+            <ul>
+            <li><p>checkout the site from the source repository:</p>
+            <p><source>svn co http://svn.apache.org/repos/asf/tiles/site/</source></p></li>
+            <li><p>go into the site directory and type:</p>
+            <p><source>mvn site</source></p></li>
+            </ul>
+            <p>You will find the generated distribution under
+            <code>{tiles-site-dir}/target/site</code>.</p>
+          </subsection>
+          <subsection name="Building a project's website">
+            <p>To build the framework website:</p>
+            <ul>
+            <li><p><a href="/download.html">download</a> the source
+            distribution, or checkout the latest version:</p>
+            <p><source>svn co http://svn.apache.org/repos/asf/tiles/framework/trunk/tiles-parent/</source></p></li>
+            <li><p>go into the source directory and type:</p>
+            <p><source>mvn site site:stage</source></p></li>
+            </ul>
+            <p>You will find the generated website under:</p>
+            <ul>
+            <li>{tiles-dir}/target/staging</li>
+            </ul>
+          </subsection>
+        </section>
+    </body>
+
+</document>
diff --git a/Java-base/tiles/src/src/site/xdoc/dev/snapshots.xml b/Java-base/tiles/src/src/site/xdoc/dev/snapshots.xml
new file mode 100644
index 000000000..d73af597a
--- /dev/null
+++ b/Java-base/tiles/src/src/site/xdoc/dev/snapshots.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0"?>
+<!--
+/*
+ * $Id$
+ *
+ * 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>Apache Tiles</title>
+    </properties>
+
+    <body>
+        <section name="Apache Tiles&#8482;">
+        <subsection name="Snapshots">
+
+        <p>Looking for snapshot builds of the latest version of Tiles?
+           Snapshots are occasionally published to Apache's Maven snapshot
+           repository, which can be accessed with the following configuration:</p>
+
+        <source>
+        <![CDATA[
+          <repository>
+              <id>apache.snapshots</id>
+              <name>Apache Maven Snapshot Repository</name>
+              <url>http://repository.apache.org/snapshots</url>
+          </repository>
+        ]]>
+        </source>
+
+        <p>After configuring the repository, declare a dependency on
+        Tiles:</p>
+
+        <source><![CDATA[
+          <dependency>
+              <groupId>org.apache.tiles</groupId>
+              <artifactId>tiles-core</artifactId>
+              <version>3.0.0-SNAPSHOT</version>
+          </dependency>
+        ]]>
+        </source>
+
+   <p>You can see Tiles in action by downloading a snapshot of the 'tiles-test' webapp,
+   <a href="http://repository.apache.org/snapshots/org/apache/tiles/tiles-test/3.0.0-SNAPSHOT">
+   here</a>.</p>
+
+    </subsection>
+</section>
+</body>
+
+</document>
diff --git a/Java-base/tiles/src/src/site/xdoc/images/page_to_page.svg b/Java-base/tiles/src/src/site/xdoc/images/page_to_page.svg
new file mode 100644
index 000000000..72ac013c0
--- /dev/null
+++ b/Java-base/tiles/src/src/site/xdoc/images/page_to_page.svg
@@ -0,0 +1,450 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://web.resource.org/cc/"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="297mm"
+   height="210mm"
+   id="svg17456"
+   sodipodi:version="0.32"
+   inkscape:version="0.45.1"
+   sodipodi:docbase="C:\Documents and Settings\Administrator\Documenti\devs\workspace\tiles-site\src\site\xdoc\images"
+   sodipodi:docname="page_to_page.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape"
+   inkscape:export-filename="C:\Documents and Settings\Administrator\Documenti\devs\workspace\tiles-site\src\site\xdoc\images\page_to_page.png"
+   inkscape:export-xdpi="45.738995"
+   inkscape:export-ydpi="45.738995">
+  <defs
+     id="defs17458">
+    <marker
+       inkscape:stockid="Arrow1Lstart"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Lstart"
+       style="overflow:visible">
+      <path
+         id="path10215"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
+         transform="scale(0.8) translate(12.5,0)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow1Lend"
+       orient="auto"
+       refY="0.0"
+       refX="0.0"
+       id="Arrow1Lend"
+       style="overflow:visible;">
+      <path
+         id="path10218"
+         d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+         style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
+         transform="scale(0.8) rotate(180) translate(12.5,0)" />
+    </marker>
+    <filter
+       y="-0.11950515"
+       x="-0.025476923"
+       height="1.2390103"
+       inkscape:collect="always"
+       id="filter16368"
+       width="1.0509538">
+      <feGaussianBlur
+         stdDeviation="5.9752577"
+         id="feGaussianBlur16370"
+         inkscape:collect="always" />
+    </filter>
+    <filter
+       y="-0.026283871"
+       x="-0.10446155"
+       height="1.0525677"
+       inkscape:collect="always"
+       id="filter16360"
+       width="1.2089231">
+      <feGaussianBlur
+         stdDeviation="5.7574194"
+         id="feGaussianBlur16362"
+         inkscape:collect="always" />
+    </filter>
+    <filter
+       id="filter16364"
+       inkscape:collect="always">
+      <feGaussianBlur
+         stdDeviation="8.1709926"
+         id="feGaussianBlur16366"
+         inkscape:collect="always" />
+    </filter>
+    <filter
+       y="-0.1026308"
+       x="-0.026569395"
+       height="1.2052616"
+       inkscape:collect="always"
+       id="filter15383"
+       width="1.0531388">
+      <feGaussianBlur
+         stdDeviation="6.2311555"
+         id="feGaussianBlur15385"
+         inkscape:collect="always" />
+    </filter>
+    <linearGradient
+       id="linearGradient9013">
+      <stop
+         offset="0"
+         style="stop-color:#0000f1;stop-opacity:1;"
+         id="stop9015" />
+      <stop
+         offset="1"
+         style="stop-color:#0000e7;stop-opacity:1;"
+         id="stop9017" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient9013"
+       id="linearGradient3270"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-85.176716,-201.15627)"
+       x1="100"
+       y1="179.50504"
+       x2="662.85712"
+       y2="179.50504" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient9013"
+       id="linearGradient3293"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-85.176716,-201.15627)"
+       x1="100"
+       y1="179.50504"
+       x2="662.85712"
+       y2="179.50504" />
+  </defs>
+  <sodipodi:namedview
+     inkscape:document-units="mm"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.73377778"
+     inkscape:cx="526.18109"
+     inkscape:cy="372.04724"
+     inkscape:current-layer="layer1"
+     id="namedview17460"
+     inkscape:window-width="1024"
+     inkscape:window-height="742"
+     inkscape:window-x="-4"
+     inkscape:window-y="-4" />
+  <metadata
+     id="metadata17462">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <rect
+       width="562.85712"
+       id="rect2164"
+       style="fill:url(#linearGradient3270);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter15383)"
+       height="145.71428"
+       x="14.823284"
+       y="-94.508362"
+       ry="39.891556"
+       rx="39.891556"
+       transform="matrix(0.5314768,0,0,0.5314768,61.511991,173.91617)" />
+    <rect
+       width="408.08701"
+       id="rect2160"
+       style="fill:#a56f63;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.97929907px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter16364)"
+       height="525.74072"
+       x="169.61116"
+       y="68.342117"
+       ry="47.144566"
+       rx="47.144566"
+       transform="matrix(0.5314768,0,0,0.5314768,61.511991,173.91617)" />
+    <rect
+       width="132.27649"
+       id="rect2166"
+       style="fill:#a42ae3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.99249059px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter16360)"
+       height="525.71429"
+       x="14.81953"
+       y="68.34877"
+       ry="36.265053"
+       rx="36.265053"
+       transform="matrix(0.5314768,0,0,0.5314768,61.511991,173.91617)" />
+    <rect
+       width="562.8866"
+       id="rect2168"
+       style="fill:#d34ba1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.98513663px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter16368)"
+       height="120"
+       x="14.815853"
+       y="614.06311"
+       ry="43.518063"
+       rx="43.518063"
+       transform="matrix(0.5314768,0,0,0.5314768,61.511991,173.91617)" />
+    <rect
+       width="335.80774"
+       id="rect2178"
+       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.01408041;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       height="471.15994"
+       x="50.299847"
+       y="108.69428"
+       ry="0"
+       rx="0" />
+    <text
+       x="155.08797"
+       y="173.56755"
+       id="text9029"
+       style="font-size:32.03010941px;font-style:normal;font-weight:normal;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       xml:space="preserve"><tspan
+         x="155.08797"
+         y="173.56755"
+         id="tspan9031"
+         sodipodi:role="line">Header</tspan></text>
+    <text
+       x="174.85722"
+       y="255.69447"
+       id="text12917"
+       style="font-size:32.03010941px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       xml:space="preserve"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan18497"
+         x="174.85722"
+         y="255.69447">Body 1</tspan></text>
+    <text
+       inkscape:transform-center-x="-61.281104"
+       xml:space="preserve"
+       inkscape:transform-center-y="218.68718"
+       id="text12921"
+       style="font-size:32.03010941px;font-style:normal;font-weight:normal;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       x="-389.19147"
+       y="113.1748"
+       transform="matrix(0,-1,1,0,0,0)"><tspan
+         x="-389.19147"
+         y="113.1748"
+         id="tspan12923"
+         sodipodi:role="line">Menu</tspan></text>
+    <text
+       x="170.38945"
+       y="539.88239"
+       id="text12925"
+       style="font-size:32.03010941px;font-style:normal;font-weight:normal;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       xml:space="preserve"><tspan
+         x="170.38945"
+         y="539.88239"
+         id="tspan12927"
+         sodipodi:role="line">Footer</tspan></text>
+    <text
+       x="54.635624"
+       y="100.42758"
+       id="text12929"
+       style="font-size:32.03010941px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       xml:space="preserve"><tspan
+         x="54.635624"
+         y="100.42758"
+         id="tspan12931"
+         sodipodi:role="line">Template</tspan></text>
+    <path
+       style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1"
+       d="M 371.94791,611.12074 L 22.947911,611.12074 L 22.947911,57.120742 L 418.94791,57.120742 L 418.94791,562.12074"
+       id="rect2193"
+       sodipodi:nodetypes="ccccc" />
+    <path
+       style="fill:#e0cdda;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.95418596;stroke-miterlimit:4;stroke-opacity:1"
+       d="M 417.97082,562.3824 L 372.54218,611.05262 C 380.85914,591.75202 374.67472,574.86832 367.26476,558.18888 C 385.05185,567.20981 390.43537,571.137 417.97082,562.3824 z "
+       id="path2208"
+       sodipodi:nodetypes="cccc" />
+    <text
+       x="20.474751"
+       y="45.45446"
+       id="text3182"
+       style="font-size:32.03010941px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       xml:space="preserve"><tspan
+         x="20.474751"
+         y="45.45446"
+         id="tspan3184"
+         sodipodi:role="line">Page 1</tspan></text>
+    <rect
+       width="562.85712"
+       id="rect3186"
+       style="fill:url(#linearGradient3293);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter15383)"
+       height="145.71428"
+       x="14.823284"
+       y="-94.508362"
+       ry="39.891556"
+       rx="39.891556"
+       transform="matrix(0.5314768,0,0,0.5314768,665.06438,174.33843)" />
+    <rect
+       width="408.08701"
+       id="rect3188"
+       style="fill:#d24d31;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.97929907px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter16364)"
+       height="525.74072"
+       x="169.61116"
+       y="68.342117"
+       ry="47.144566"
+       rx="47.144566"
+       transform="matrix(0.5314768,0,0,0.5314768,665.06438,174.33843)" />
+    <rect
+       width="132.27649"
+       id="rect3190"
+       style="fill:#a42ae3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.99249059px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter16360)"
+       height="525.71429"
+       x="14.81953"
+       y="68.34877"
+       ry="36.265053"
+       rx="36.265053"
+       transform="matrix(0.5314768,0,0,0.5314768,665.06438,174.33843)" />
+    <rect
+       width="562.8866"
+       id="rect3192"
+       style="fill:#d34ba1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.98513663px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter16368)"
+       height="120"
+       x="14.815853"
+       y="614.06311"
+       ry="43.518063"
+       rx="43.518063"
+       transform="matrix(0.5314768,0,0,0.5314768,665.06438,174.33843)" />
+    <rect
+       width="335.80774"
+       id="rect3194"
+       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.01408041;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       height="471.15994"
+       x="653.85223"
+       y="109.11654"
+       ry="0"
+       rx="0" />
+    <text
+       x="758.64038"
+       y="173.98979"
+       id="text3196"
+       style="font-size:32.03010941px;font-style:normal;font-weight:normal;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       xml:space="preserve"><tspan
+         x="758.64038"
+         y="173.98979"
+         id="tspan3198"
+         sodipodi:role="line">Header</tspan></text>
+    <text
+       x="811.11707"
+       y="352.87628"
+       id="text3200"
+       style="font-size:32.03010941px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       xml:space="preserve"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         x="811.11707"
+         y="352.87628"
+         id="tspan3314">Body 2</tspan></text>
+    <text
+       inkscape:transform-center-x="-61.281104"
+       xml:space="preserve"
+       inkscape:transform-center-y="218.68718"
+       id="text3204"
+       style="font-size:32.03010941px;font-style:normal;font-weight:normal;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       x="-389.61377"
+       y="716.72717"
+       transform="matrix(0,-1,1,0,0,0)"><tspan
+         x="-389.61377"
+         y="716.72717"
+         id="tspan3206"
+         sodipodi:role="line">Menu</tspan></text>
+    <text
+       x="773.94183"
+       y="540.30469"
+       id="text3208"
+       style="font-size:32.03010941px;font-style:normal;font-weight:normal;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       xml:space="preserve"><tspan
+         x="773.94183"
+         y="540.30469"
+         id="tspan3210"
+         sodipodi:role="line">Footer</tspan></text>
+    <text
+       x="658.18799"
+       y="100.84985"
+       id="text3212"
+       style="font-size:32.03010941px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       xml:space="preserve"><tspan
+         x="658.18799"
+         y="100.84985"
+         id="tspan3214"
+         sodipodi:role="line">Template</tspan></text>
+    <path
+       style="fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1"
+       d="M 975.5003,611.543 L 626.5003,611.543 L 626.5003,57.543004 L 1022.5003,57.543004 L 1022.5003,562.543"
+       id="path3216"
+       sodipodi:nodetypes="ccccc" />
+    <path
+       style="fill:#e0cdda;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.95418596;stroke-miterlimit:4;stroke-opacity:1"
+       d="M 1021.5232,562.80466 L 976.09457,611.47488 C 984.41153,592.17428 978.22711,575.29058 970.81715,558.61114 C 988.60424,567.63207 993.98776,571.55926 1021.5232,562.80466 z "
+       id="path3218"
+       sodipodi:nodetypes="cccc" />
+    <text
+       x="624.0271"
+       y="45.876732"
+       id="text3220"
+       style="font-size:32.03010941px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       xml:space="preserve"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan3226"
+         x="624.0271"
+         y="45.876732">Page 2</tspan></text>
+    <g
+       id="g7251"
+       transform="translate(-24.530587,0)">
+      <text
+         sodipodi:linespacing="125%"
+         xml:space="preserve"
+         style="font-size:22.17276764px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+         id="text4326"
+         y="336.59854"
+         x="189.11517"><tspan
+           y="336.59854"
+           x="189.11517"
+           id="tspan4328"
+           sodipodi:role="line">Link to Page 2</tspan></text>
+      <path
+         id="path4338"
+         d="M 190.79346,343.42822 C 195.47152,343.42822 209.08858,343.42822 218.04967,343.42822 C 225.31799,343.42822 232.58631,343.42822 239.85463,343.42822 C 247.12295,343.42822 254.39128,343.42822 261.6596,343.42822 C 269.38219,343.42822 277.10478,343.42822 284.82738,343.42822 C 292.54997,343.42822 300.27256,343.42822 307.99515,343.42822 C 314.8092,343.42822 321.62326,343.42822 328.43731,343.42822 C 333.88855,343.42822 339.33979,343.42822 344.79103,343.42822"
+         style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:2.06220484;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    </g>
+    <path
+       style="opacity:1;fill:#2e54e9;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.84306264;stroke-linecap:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="M 596.5625 312.96875 L 596.5625 325.4375 L 322.71875 325.4375 L 322.71875 331.4375 L 596.5625 331.4375 L 596.5625 343.71875 L 623.1875 328.34375 L 596.5625 312.96875 z "
+       id="rect14612" />
+  </g>
+</svg>
diff --git a/Java-base/tiles/src/src/site/xdoc/images/tiled_page.svg b/Java-base/tiles/src/src/site/xdoc/images/tiled_page.svg
new file mode 100644
index 000000000..7fe04ff09
--- /dev/null
+++ b/Java-base/tiles/src/src/site/xdoc/images/tiled_page.svg
@@ -0,0 +1,277 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://web.resource.org/cc/"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="744.09448819"
+   height="1052.3622047"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.45.1"
+   sodipodi:docbase="C:\Documents and Settings\Administrator\Documenti\devs\workspace\tiles-site\src\site\xdoc\images"
+   sodipodi:docname="tiled_page.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape"
+   inkscape:export-filename="C:\Documents and Settings\PTRNTN77A26E506O\Documenti\disegno.png"
+   inkscape:export-xdpi="23.716087"
+   inkscape:export-ydpi="23.716087">
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.51883278"
+     inkscape:cx="372.04724"
+     inkscape:cy="526.18109"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     inkscape:window-width="1024"
+     inkscape:window-height="742"
+     inkscape:window-x="-4"
+     inkscape:window-y="-4"
+     showguides="true"
+     showgrid="false"
+     width="131.10236px"
+     height="184.25197px" />
+  <defs
+     id="defs4">
+    <linearGradient
+       id="linearGradient9013">
+      <stop
+         offset="0"
+         style="stop-color:#0000f1;stop-opacity:1;"
+         id="stop9015" />
+      <stop
+         offset="1"
+         style="stop-color:#0000e7;stop-opacity:1;"
+         id="stop9017" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient6077">
+      <stop
+         offset="0"
+         style="stop-color:#0000ff;stop-opacity:1;"
+         id="stop6079" />
+      <stop
+         offset="0.125"
+         style="stop-color:#0000ff;stop-opacity:0.8745098;"
+         id="stop7064" />
+      <stop
+         offset="0.25"
+         style="stop-color:#0000ff;stop-opacity:0.74901961;"
+         id="stop6091" />
+      <stop
+         offset="0.5"
+         style="stop-color:#0000ff;stop-opacity:0.49803922;"
+         id="stop6089" />
+      <stop
+         offset="1"
+         style="stop-color:#0000ff;stop-opacity:0;"
+         id="stop6081" />
+    </linearGradient>
+    <linearGradient
+       x2="662.85712"
+       y2="179.50504"
+       inkscape:collect="always"
+       x1="100"
+       id="linearGradient9019"
+       y1="179.50504"
+       xlink:href="#linearGradient9013"
+       gradientUnits="userSpaceOnUse" />
+    <filter
+       y="-0.1026308"
+       x="-0.026569395"
+       height="1.2052616"
+       inkscape:collect="always"
+       id="filter15383"
+       width="1.0531388">
+      <feGaussianBlur
+         stdDeviation="6.2311555"
+         id="feGaussianBlur15385"
+         inkscape:collect="always" />
+    </filter>
+    <filter
+       y="-0.026283871"
+       x="-0.10446155"
+       height="1.0525677"
+       inkscape:collect="always"
+       id="filter16360"
+       width="1.2089231">
+      <feGaussianBlur
+         stdDeviation="5.7574194"
+         id="feGaussianBlur16362"
+         inkscape:collect="always" />
+    </filter>
+    <filter
+       id="filter16364"
+       inkscape:collect="always">
+      <feGaussianBlur
+         stdDeviation="8.1709926"
+         id="feGaussianBlur16366"
+         inkscape:collect="always" />
+    </filter>
+    <filter
+       y="-0.11950515"
+       x="-0.025476923"
+       height="1.2390103"
+       inkscape:collect="always"
+       id="filter16368"
+       width="1.0509538">
+      <feGaussianBlur
+         stdDeviation="5.9752577"
+         id="feGaussianBlur16370"
+         inkscape:collect="always" />
+    </filter>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient9013"
+       id="linearGradient16485"
+       gradientUnits="userSpaceOnUse"
+       x1="100"
+       y1="179.50504"
+       x2="662.85712"
+       y2="179.50504" />
+  </defs>
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Livello 1"
+     id="layer1"
+     inkscape:groupmode="layer">
+    <rect
+       width="562.85712"
+       id="rect2164"
+       style="fill:url(#linearGradient16485);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter15383)"
+       height="145.71428"
+       x="100"
+       y="106.6479"
+       ry="21.201435"
+       rx="21.201435" />
+    <rect
+       width="408.08701"
+       id="rect2160"
+       style="fill:#a56f63;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.97929907px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter16364)"
+       height="525.74072"
+       x="254.78787"
+       y="269.49838"
+       ry="25.056242"
+       rx="25.056242" />
+    <rect
+       width="132.27649"
+       id="rect2166"
+       style="fill:#a42ae3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.99249059px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter16360)"
+       height="525.71429"
+       x="99.996246"
+       y="269.50504"
+       ry="19.274033"
+       rx="19.274033" />
+    <rect
+       width="562.8866"
+       id="rect2168"
+       style="fill:#d34ba1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.98513663px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter16368)"
+       height="120"
+       x="99.992569"
+       y="815.21936"
+       ry="23.128839"
+       rx="23.128839" />
+    <rect
+       width="631.83899"
+       id="rect2178"
+       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.90804267;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       height="886.51086"
+       x="64.080521"
+       y="78.438026"
+       ry="22.219292"
+       rx="21.853825" />
+    <text
+       x="261.2446"
+       y="200.50032"
+       id="text9029"
+       style="font-size:60.2662468px;font-style:normal;font-weight:normal;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       xml:space="preserve"><tspan
+         x="261.2446"
+         y="200.50032"
+         id="tspan9031"
+         sodipodi:role="line">Header</tspan></text>
+    <text
+       x="378.79764"
+       y="537.08411"
+       id="text12917"
+       style="font-size:60.2662468px;font-style:normal;font-weight:normal;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       xml:space="preserve"><tspan
+         x="378.79764"
+         y="537.08411"
+         id="tspan12919"
+         sodipodi:role="line">Body</tspan></text>
+    <text
+       inkscape:transform-center-x="-29.162036"
+       xml:space="preserve"
+       inkscape:transform-center-y="-34.693259"
+       id="text12921"
+       style="font-size:60.2662468px;font-style:normal;font-weight:normal;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       x="-606.20746"
+       y="182.38286"
+       transform="matrix(0,-1,1,0,0,0)"><tspan
+         x="-606.20746"
+         y="182.38286"
+         id="tspan12923"
+         sodipodi:role="line">Menu</tspan></text>
+    <text
+       x="290.0351"
+       y="889.73987"
+       id="text12925"
+       style="font-size:60.2662468px;font-style:normal;font-weight:normal;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       xml:space="preserve"><tspan
+         x="290.0351"
+         y="889.73987"
+         id="tspan12927"
+         sodipodi:role="line">Footer</tspan></text>
+    <text
+       x="72.238495"
+       y="62.883839"
+       id="text12929"
+       style="font-size:60.2662468px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       xml:space="preserve"><tspan
+         x="72.238495"
+         y="62.883839"
+         id="tspan12931"
+         sodipodi:role="line">Template</tspan></text>
+  </g>
+</svg>
diff --git a/Java-base/tiles/src/tiles-api/pom.xml b/Java-base/tiles/src/tiles-api/pom.xml
new file mode 100644
index 000000000..5d1749d45
--- /dev/null
+++ b/Java-base/tiles/src/tiles-api/pom.xml
@@ -0,0 +1,99 @@
+<?xml version="1.0"?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <parent>
+        <groupId>org.apache.tiles</groupId>
+        <artifactId>tiles-parent</artifactId>
+        <version>3.1-SNAPSHOT</version>
+    </parent>
+
+    <modelVersion>4.0.0</modelVersion>
+    <artifactId>tiles-api</artifactId>
+    <packaging>jar</packaging>
+    <name>Tiles - API</name>
+    <description>Tiles APIs, containing interfaces and classes to interact with
+    Tiles.</description>
+
+    <properties>
+        <tiles.osgi.symbolicName>org.apache.tiles.api</tiles.osgi.symbolicName>
+      <!-- decrease this whenever possible -->
+      <checkstyle.maxAllowedViolations>5</checkstyle.maxAllowedViolations>
+    </properties>
+
+    <build>
+
+        <resources>
+            <resource>
+                <directory>src/main/resources</directory>
+                <excludes>
+                    <exclude>LICENSE.txt</exclude>
+                    <exclude>NOTICE.txt</exclude>
+                </excludes>
+            </resource>
+            <resource>
+                <directory>src/main/resources</directory>
+                <includes>
+                    <include>LICENSE.txt</include>
+                    <include>NOTICE.txt</include>
+                </includes>
+                <targetPath>META-INF</targetPath>
+            </resource>
+        </resources>
+
+    </build>
+
+    <dependencies>
+
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>servlet-api</artifactId>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+              <groupId>junit</groupId>
+              <artifactId>junit</artifactId>
+              <scope>test</scope>
+          </dependency>
+        <dependency>
+              <groupId>org.easymock</groupId>
+              <artifactId>easymockclassextension</artifactId>
+              <scope>test</scope>
+          </dependency>
+        <dependency>
+              <groupId>org.slf4j</groupId>
+              <artifactId>slf4j-api</artifactId>
+        </dependency>
+        <dependency>
+              <groupId>org.slf4j</groupId>
+              <artifactId>slf4j-jdk14</artifactId>
+              <scope>test</scope>
+        </dependency>
+        <dependency>
+        	<groupId>org.apache.tiles</groupId>
+        	<artifactId>tiles-request-api</artifactId>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/Attribute.java b/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/Attribute.java
new file mode 100644
index 000000000..ee0652cb1
--- /dev/null
+++ b/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/Attribute.java
@@ -0,0 +1,384 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles;
+
+import static org.apache.tiles.CompareUtil.*;
+
+import java.io.Serializable;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.apache.tiles.request.Request;
+
+/**
+ * Common implementation of attribute definition.
+ *
+ * @version $Rev$ $Date$
+ */
+public class Attribute implements Serializable, Cloneable {
+
+    /**
+     * The name of the template renderer.
+     */
+    private static final String TEMPLATE_RENDERER = "template";
+
+    /**
+     * The roles that can render this attribute.
+     * @since 2.0.6
+     */
+    protected Set<String> roles = null;
+
+    /**
+     * The value of the attribute.
+     */
+    protected Object value = null;
+
+    /**
+     * The expression to evaluate. Ignored if {@link #value} is not
+     * <code>null</code>.
+     *
+     * @since 2.2.0
+     */
+    protected Expression expressionObject = null;
+
+    /**
+     * The renderer name of the attribute. Default names are <code>string</code>,
+     * <code>template</code>, <code>definition</code>, <code>object</code>.
+     */
+    private String renderer = null;
+
+    /**
+     * Constructor.
+     *
+     */
+    public Attribute() {
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param value Object to store.
+     */
+    public Attribute(Object value) {
+        this.value = value;
+    }
+
+    /**
+     * Copy constructor.
+     *
+     * @param attribute The attribute to copy from.
+     */
+    public Attribute(Attribute attribute) {
+        this.roles = attribute.roles;
+        this.value = attribute.getValue();
+        if (attribute.expressionObject != null) {
+            this.expressionObject = new Expression(attribute.expressionObject);
+        } else {
+            this.expressionObject = null;
+        }
+        this.renderer = attribute.renderer;
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param value Object to store.
+     * @param role  Asociated role.
+     */
+    public Attribute(Object value, String role) {
+        this.value = value;
+        setRole(role);
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param value Object to store. If specified, the <code>expression</code>
+     * parameter will be ignored.
+     * @param expression The expression to be evaluated. Ignored if the
+     * <code>value</code> is not null.
+     * @param role Associated role.
+     * @param rendererName The renderer name.
+     * @since 2.2.0
+     */
+    public Attribute(Object value, Expression expression, String role, String rendererName) {
+        this.value = value;
+        this.expressionObject = expression;
+        this.renderer = rendererName;
+        setRole(role);
+    }
+
+    /**
+     * Creates a template attribute, starting from the name of the template.
+     *
+     * @param template The template that will be rendered.
+     * @return The template attribute.
+     * @since 2.1.2
+     */
+    public static Attribute createTemplateAttribute(String template) {
+        Attribute attribute = new Attribute();
+        attribute.setValue(template);
+        attribute.setRenderer(TEMPLATE_RENDERER);
+        return attribute;
+    }
+
+    /**
+     * Creates a template attribute, starting from the name of the template.
+     *
+     * @param template The template that will be rendered.
+     * @param templateExpression The template expression that will be evaluated
+     * to a template.
+     * @param templateType The type, or renderer, of the template. If null, the
+     * default <code>template</code> will be used.
+     * @param role The comma-separated roles for which the template is
+     * authorized to be rendered.
+     * @return The template attribute.
+     * @since 2.2.2
+     */
+    public static Attribute createTemplateAttribute(String template,
+            String templateExpression, String templateType, String role) {
+        Attribute templateAttribute = createTemplateAttribute(template);
+        templateAttribute.setRole(role);
+        if (templateType != null) {
+            templateAttribute.setRenderer(templateType);
+        }
+        templateAttribute
+                .setExpressionObject(Expression
+                        .createExpressionFromDescribedExpression(templateExpression));
+        return templateAttribute;
+    }
+
+    /**
+     * Creates a template attribute, starting from the expression to evaluate to
+     * obtain the template.
+     *
+     * @param templateExpression The expression to evaluate.
+     * @return The template attribute.
+     * @since 2.1.2
+     */
+    public static Attribute createTemplateAttributeWithExpression(
+            String templateExpression) {
+        Attribute attribute = new Attribute();
+        attribute.setExpressionObject(new Expression(templateExpression));
+        attribute.setRenderer(TEMPLATE_RENDERER);
+        return attribute;
+    }
+
+    /**
+     * Get role.
+     * @return the name of the required role(s)
+     */
+    public String getRole() {
+        String retValue = null;
+
+        if (roles != null && !roles.isEmpty()) {
+            StringBuilder builder = new StringBuilder();
+            Iterator<String> roleIt = roles.iterator();
+            if (roleIt.hasNext()) {
+                builder.append(roleIt.next());
+                while (roleIt.hasNext()) {
+                    builder.append(",");
+                    builder.append(roleIt.next());
+                }
+                retValue = builder.toString();
+            }
+        }
+
+        return retValue;
+    }
+
+    /**
+     * Returns the roles that can render this attribute.
+     *
+     * @return The enabled roles.
+     * @since 2.0.6
+     */
+    public Set<String> getRoles() {
+        return roles;
+    }
+
+    /**
+     * Set role.
+     *
+     * @param role Associated role.
+     */
+    public void setRole(String role) {
+        if (role != null && role.trim().length() > 0) {
+            String[] rolesStrings = role.split("\\s*,\\s*");
+            roles = new HashSet<String>();
+            for (int i = 0; i < rolesStrings.length; i++) {
+                roles.add(rolesStrings[i]);
+            }
+        } else {
+            roles = null;
+        }
+    }
+
+    /**
+     * Sets the roles that can render this attribute.
+     *
+     * @param roles The enabled roles.
+     * @since 2.0.6
+     */
+    public void setRoles(Set<String> roles) {
+        this.roles = roles;
+    }
+
+    /**
+     * Get value.
+     * @return the value
+     */
+    public Object getValue() {
+        return value;
+    }
+
+    /**
+     * Set value.
+     *
+     * @param value New value.
+     */
+    public void setValue(Object value) {
+        this.value = value;
+    }
+
+    /**
+     * Returns The expression to evaluate. Ignored if {@link #value} is not
+     * <code>null</code>.
+     *
+     * @return The expression to be evaluated.
+     * @since 2.2.0
+     */
+    public Expression getExpressionObject() {
+        return expressionObject;
+    }
+
+    /**
+     * Sets The expression to evaluate. Ignored if {@link #value} is not
+     * <code>null</code>.
+     *
+     * @param expressionObject The expression to be evaluated.
+     * @since 2.2.0
+     */
+    public void setExpressionObject(Expression expressionObject) {
+        this.expressionObject = expressionObject;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public String toString() {
+        if (value != null) {
+            return value.toString();
+        }
+        return null;
+    }
+
+    /**
+     * Returns the renderer name to use.
+     *
+     * @return The renderer name.
+     * @since 2.1.0
+     */
+    public String getRenderer() {
+        return renderer;
+    }
+
+    /**
+     * Sets the renderer name to use.
+     *
+     * @param rendererName The renderer.
+     * @since 2.1.0
+     */
+    public void setRenderer(String rendererName) {
+        this.renderer = rendererName;
+    }
+
+    /**
+     * Inherits an attribute, i.e. overwrites null properties with the ones
+     * provided by the attribute.
+     *
+     * @param attribute The attribute to inherit.
+     * @since 2.1.2
+     */
+    public void inherit(Attribute attribute) {
+        if (value == null) {
+            value = attribute.getValue();
+        }
+        Expression targetExpressionObject = attribute.getExpressionObject();
+        if (targetExpressionObject != null
+                && (expressionObject == null || expressionObject
+                        .getExpression() == null)) {
+            expressionObject = new Expression(targetExpressionObject);
+        }
+        if (roles == null || roles.isEmpty()) {
+            roles = attribute.getRoles();
+        }
+        if (renderer == null) {
+            renderer = attribute.getRenderer();
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean equals(Object obj) {
+        Attribute attribute = (Attribute) obj;
+        return nullSafeEquals(value, attribute.value)
+                && nullSafeEquals(renderer, attribute.renderer)
+                && nullSafeEquals(roles, attribute.roles)
+                && nullSafeEquals(expressionObject, attribute.expressionObject);
+    }
+
+    /**
+     * Checks if the current user can use this attribute.
+     *
+     * @param request The request context.
+     * @return <code>true</code> if the current user can see this attribute.
+     * @since 3.0.0
+     */
+    public boolean isPermitted(Request request) {
+        if (roles == null || roles.isEmpty()) {
+            return true;
+        }
+
+        boolean retValue = false;
+
+        for (Iterator<String> roleIt = roles.iterator(); roleIt.hasNext()
+                && !retValue;) {
+            retValue = request.isUserInRole(roleIt.next());
+        }
+
+        return retValue;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int hashCode() {
+        return nullSafeHashCode(value) + nullSafeHashCode(renderer)
+                + nullSafeHashCode(roles) + nullSafeHashCode(expressionObject);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Attribute clone() {
+        return new Attribute(this);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/AttributeContext.java b/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/AttributeContext.java
new file mode 100644
index 000000000..ab899ec2e
--- /dev/null
+++ b/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/AttributeContext.java
@@ -0,0 +1,171 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles;
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Encapsulation of the current state of execution.
+ *
+ * @since Tiles 2.0
+ * @version $Rev$ $Date$
+ */
+public interface AttributeContext {
+
+    /**
+     * Returns the attribute that will be used to render a template.
+     *
+     * @return The template attribute.
+     * @since 2.1.2
+     */
+    Attribute getTemplateAttribute();
+
+    /**
+     * Sets the template attribute, that will be used to render the template
+     * page.
+     *
+     * @param templateAttribute The template attribute.
+     * @since 2.1.2
+     */
+    void setTemplateAttribute(Attribute templateAttribute);
+
+    /**
+     * Get associated preparer instance.
+     *
+     * @return The preparer name.
+     * @since 2.1.0
+     */
+    String getPreparer();
+
+    /**
+     * Set associated preparer instance.
+     *
+     * @param url The preparer name.
+     * @since 2.1.0
+     */
+    void setPreparer(String url);
+
+    /**
+     * Add all attributes to the context.
+     *
+     * @param newAttributes the attributes to be added.
+     */
+    void addAll(Map<String, Attribute> newAttributes);
+
+    /**
+     * Add all attributes to the context.
+     *
+     * @param defaultAttributes attributes which should be present.
+     */
+    void addMissing(Map<String, Attribute> defaultAttributes);
+
+    /**
+     * Copies the cascaded attributes to this attribute context.
+     *
+     * @param parent The parent context to be used.
+     * @since 2.1.0
+     */
+    void inheritCascadedAttributes(AttributeContext parent);
+
+    /**
+     * Copies all missing attributes from the <code>parent</code> attribute
+     * context to this one.
+     *
+     * @param parent The attribute context to copy attributes from.
+     * @since 2.1.0
+     */
+    void inherit(AttributeContext parent);
+
+    /**
+     * Retrieve the named attribute, either cascaded or not.
+     *
+     * @param name key name for the attribute.
+     * @return Attribute associated with the given name.
+     */
+    Attribute getAttribute(String name);
+
+    /**
+     * Retrieve the attribute that has been defined in this context (i.e. not
+     * cascaded).
+     *
+     * @param name key name for the attribute.
+     * @return Attribute The local attribute associated with the given name, if
+     * present, or <code>null</code> otherwise.
+     * @since 2.1.0
+     */
+    Attribute getLocalAttribute(String name);
+
+    /**
+     * Retrieve the attribute that has been cascaded at upper levels.
+     *
+     * @param name key name for the attribute.
+     * @return Attribute The cascaded attribute associated with the given name,
+     * if present, or <code>null</code> otherwise.
+     * @since 2.1.0
+     */
+    Attribute getCascadedAttribute(String name);
+
+    /**
+     * Returns the names of the local attributes, i.e. the one that have not
+     * been cascaded.
+     *
+     * @return The local attribute names.
+     * @since 2.1.0
+     */
+    Set<String> getLocalAttributeNames();
+
+    /**
+     * Returns the names of the cascaded attributes.
+     *
+     * @return The cascaded attribute names.
+     * @since 2.1.0
+     */
+    Set<String> getCascadedAttributeNames();
+
+    /**
+     * Add the specified attribute. The attribute value will be available only
+     * in the current context, i.e. it is like calling
+     * {@link AttributeContext#putAttribute(String, Attribute, boolean)} with
+     * <code>cascade = false</code>.
+     *
+     * @param name name of the attribute
+     * @param value value of the attribute
+     */
+    void putAttribute(String name, Attribute value);
+
+    /**
+     * Add the specified attribute.
+     *
+     * @param name name of the attribute
+     * @param value value of the attribute
+     * @param cascade If <code>true</code>, the attribute value will be
+     * available in all nested contexts. If <code>false</code>, it will be
+     * available only in the current context.
+     * @since 2.1.0
+     */
+    void putAttribute(String name, Attribute value, boolean cascade);
+
+    /**
+     * Clear the attributes.
+     */
+    void clear();
+}
diff --git a/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/BasicAttributeContext.java b/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/BasicAttributeContext.java
new file mode 100644
index 000000000..d6cfc7f67
--- /dev/null
+++ b/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/BasicAttributeContext.java
@@ -0,0 +1,471 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles;
+
+import static org.apache.tiles.CompareUtil.*;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+
+/**
+ * Basic implementation for <code>AttributeContext</code>.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.1.0
+ */
+public class BasicAttributeContext implements AttributeContext, Serializable {
+
+    /**
+     * The template attribute, to render a template.
+     *
+     * @since 2.1.2
+     */
+    protected Attribute templateAttribute;
+
+    /**
+     * Associated ViewPreparer URL or classname, if defined.
+     *
+     * @since 2.1.0
+     */
+    protected String preparer = null;
+
+    /**
+     * Template attributes.
+     * @since 2.1.0
+     */
+    protected Map<String, Attribute> attributes = null;
+
+    /**
+     * Cascaded template attributes.
+     * @since 2.1.0
+     */
+    protected Map<String, Attribute> cascadedAttributes = null;
+
+    /**
+     * Constructor.
+     *
+     * @since 2.1.0
+     */
+    public BasicAttributeContext() {
+    }
+
+    /**
+     * Constructor.
+     * Create a context and set specified attributes.
+     *
+     * @param attributes Attributes to initialize context.
+     * @since 2.1.0
+     */
+    public BasicAttributeContext(Map<String, Attribute> attributes) {
+        if (attributes != null) {
+            this.attributes = deepCopyAttributeMap(attributes);
+        }
+    }
+
+    /**
+     * Copy constructor.
+     *
+     * @param context The constructor to copy.
+     * @since 2.1.0
+     */
+    public BasicAttributeContext(AttributeContext context) {
+        if (context instanceof BasicAttributeContext) {
+            copyBasicAttributeContext((BasicAttributeContext) context);
+        } else {
+            Attribute parentTemplateAttribute = context.getTemplateAttribute();
+            if (parentTemplateAttribute != null) {
+                this.templateAttribute = new Attribute(parentTemplateAttribute);
+            }
+            this.preparer = context.getPreparer();
+            this.attributes = new HashMap<String, Attribute>();
+            Set<String> parentAttributeNames = context.getLocalAttributeNames();
+            if (parentAttributeNames != null) {
+                for (String name : parentAttributeNames) {
+                    attributes.put(name, new Attribute(context.getLocalAttribute(name)));
+                }
+            }
+            inheritCascadedAttributes(context);
+        }
+    }
+
+    /**
+     * Copy constructor.
+     *
+     * @param context The constructor to copy.
+     * @since 2.1.0
+     */
+    public BasicAttributeContext(BasicAttributeContext context) {
+        copyBasicAttributeContext(context);
+    }
+
+    /** {@inheritDoc} */
+    public Attribute getTemplateAttribute() {
+        return templateAttribute;
+    }
+
+    /** {@inheritDoc} */
+    public void setTemplateAttribute(Attribute templateAttribute) {
+        this.templateAttribute = templateAttribute;
+    }
+
+    /** {@inheritDoc} */
+    public String getPreparer() {
+        return preparer;
+    }
+
+    /** {@inheritDoc} */
+    public void setPreparer(String url) {
+        this.preparer = url;
+    }
+
+    /** {@inheritDoc} */
+    public void inheritCascadedAttributes(AttributeContext context) {
+        if (context instanceof BasicAttributeContext) {
+            copyCascadedAttributes((BasicAttributeContext) context);
+        } else {
+            this.cascadedAttributes = new HashMap<String, Attribute>();
+            Set<String> parentAttributeNames = context.getCascadedAttributeNames();
+            if (parentAttributeNames != null) {
+                for (String name : parentAttributeNames) {
+                    cascadedAttributes.put(name, new Attribute(context
+                            .getCascadedAttribute(name)));
+                }
+            }
+        }
+    }
+
+    /** {@inheritDoc} */
+    public void inherit(AttributeContext parent) {
+        if (parent instanceof BasicAttributeContext) {
+            inherit((BasicAttributeContext) parent);
+        } else {
+            // Inheriting template, roles and preparer.
+            Attribute parentTemplateAttribute = parent.getTemplateAttribute();
+            inheritParentTemplateAttribute(parentTemplateAttribute);
+            if (preparer == null) {
+                preparer = parent.getPreparer();
+            }
+
+            // Inheriting attributes.
+            Set<String> names = parent.getCascadedAttributeNames();
+            if (names != null && !names.isEmpty()) {
+                for (String name : names) {
+                    Attribute attribute = parent.getCascadedAttribute(name);
+                    Attribute destAttribute = getCascadedAttribute(name);
+                    if (destAttribute == null) {
+                        putAttribute(name, attribute, true);
+                    } else if (attribute instanceof ListAttribute
+                            && destAttribute instanceof ListAttribute
+                            && ((ListAttribute) destAttribute).isInherit()) {
+                        ((ListAttribute) destAttribute).inherit((ListAttribute) attribute);
+                    }
+                }
+            }
+            names = parent.getLocalAttributeNames();
+            if (names != null && !names.isEmpty()) {
+                for (String name : names) {
+                    Attribute attribute = parent.getLocalAttribute(name);
+                    Attribute destAttribute = getLocalAttribute(name);
+                    if (destAttribute == null) {
+                        putAttribute(name, attribute, false);
+                    } else if (attribute instanceof ListAttribute
+                            && destAttribute instanceof ListAttribute
+                            && ((ListAttribute) destAttribute).isInherit()) {
+                        ((ListAttribute) destAttribute).inherit((ListAttribute) attribute);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Inherits the attribute context, inheriting, i.e. copying if not present,
+     * the attributes.
+     *
+     * @param parent The attribute context to inherit.
+     * @since 2.1.0
+     */
+    public void inherit(BasicAttributeContext parent) {
+        // Set template, roles and preparer if not set.
+        inheritParentTemplateAttribute(parent.getTemplateAttribute());
+        if (preparer == null) {
+            preparer = parent.preparer;
+        }
+
+        // Sets attributes.
+        cascadedAttributes = addMissingAttributes(parent.cascadedAttributes,
+                cascadedAttributes);
+        attributes = addMissingAttributes(parent.attributes, attributes);
+    }
+
+    /**
+     * Add all attributes to this context.
+     * Copies all of the mappings from the specified attribute map to this context.
+     * New attribute mappings will replace any mappings that this context had for any of the keys
+     * currently in the specified attribute map.
+     *
+     * @param newAttributes Attributes to add.
+     * @since 2.1.0
+     */
+    public void addAll(Map<String, Attribute> newAttributes) {
+        if (newAttributes == null) {
+            return;
+        }
+
+        if (attributes == null) {
+            attributes = new HashMap<String, Attribute>(newAttributes);
+            return;
+        }
+
+        attributes.putAll(newAttributes);
+    }
+
+    /**
+     * Add all missing attributes to this context.
+     * Copies all of the mappings from the specified attributes map to this context.
+     * New attribute mappings will be added only if they don't already exist in
+     * this context.
+     *
+     * @param defaultAttributes Attributes to add.
+     * @since 2.1.0
+     */
+    public void addMissing(Map<String, Attribute> defaultAttributes) {
+        if (defaultAttributes == null) {
+            return;
+        }
+
+        if (attributes == null) {
+            attributes = new HashMap<String, Attribute>();
+            if (cascadedAttributes == null || cascadedAttributes.isEmpty()) {
+                attributes.putAll(defaultAttributes);
+                return;
+            }
+        }
+
+        Set<Map.Entry<String, Attribute>> entries = defaultAttributes.entrySet();
+        for (Map.Entry<String, Attribute> entry : entries) {
+            String key = entry.getKey();
+            if (!attributes.containsKey(key)
+                    && (cascadedAttributes == null || !cascadedAttributes
+                            .containsKey(key))) {
+                attributes.put(entry.getKey(), entry.getValue());
+            }
+        }
+    }
+
+    /** {@inheritDoc} */
+    public Attribute getAttribute(String name) {
+        Attribute retValue = null;
+        if (attributes != null) {
+            retValue = attributes.get(name);
+        }
+
+        if (retValue == null && cascadedAttributes != null) {
+            retValue = cascadedAttributes.get(name);
+        }
+
+        return retValue;
+    }
+
+    /** {@inheritDoc} */
+    public Attribute getLocalAttribute(String name) {
+        if (attributes == null) {
+            return null;
+        }
+
+        return attributes.get(name);
+    }
+
+    /** {@inheritDoc} */
+    public Attribute getCascadedAttribute(String name) {
+        if (cascadedAttributes == null) {
+            return null;
+        }
+
+        return cascadedAttributes.get(name);
+    }
+
+    /** {@inheritDoc} */
+    public Set<String> getLocalAttributeNames() {
+        if (attributes != null && !attributes.isEmpty()) {
+            return attributes.keySet();
+        }
+        return null;
+    }
+
+    /** {@inheritDoc} */
+    public Set<String> getCascadedAttributeNames() {
+        if (cascadedAttributes != null && !cascadedAttributes.isEmpty()) {
+            return cascadedAttributes.keySet();
+        }
+        return null;
+    }
+
+    /** {@inheritDoc} */
+    public void putAttribute(String name, Attribute value) {
+        if (attributes == null) {
+            attributes = new HashMap<String, Attribute>();
+        }
+
+        attributes.put(name, value);
+    }
+
+    /** {@inheritDoc} */
+    public void putAttribute(String name, Attribute value, boolean cascade) {
+        Map<String, Attribute> mapToUse;
+        if (cascade) {
+            if (cascadedAttributes == null) {
+                cascadedAttributes = new HashMap<String, Attribute>();
+            }
+            mapToUse = cascadedAttributes;
+        } else {
+            if (attributes == null) {
+                attributes = new HashMap<String, Attribute>();
+            }
+            mapToUse = attributes;
+        }
+        mapToUse.put(name, value);
+    }
+
+    /** {@inheritDoc} */
+    public void clear() {
+        templateAttribute = null;
+        preparer = null;
+        attributes.clear();
+        cascadedAttributes.clear();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean equals(Object obj) {
+        BasicAttributeContext bac = (BasicAttributeContext) obj;
+        return nullSafeEquals(templateAttribute, bac.templateAttribute)
+                && nullSafeEquals(preparer, bac.preparer)
+                && nullSafeEquals(attributes, bac.attributes)
+                && nullSafeEquals(cascadedAttributes, bac.cascadedAttributes);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int hashCode() {
+        return nullSafeHashCode(templateAttribute) + nullSafeHashCode(preparer)
+                + nullSafeHashCode(attributes)
+                + nullSafeHashCode(cascadedAttributes);
+    }
+
+    /**
+     * Inherits the parent template attribute.
+     *
+     * @param parentTemplateAttribute The parent template attribute.
+     */
+    private void inheritParentTemplateAttribute(
+            Attribute parentTemplateAttribute) {
+        if (parentTemplateAttribute != null) {
+            if (templateAttribute == null) {
+                templateAttribute = new Attribute(parentTemplateAttribute);
+            } else {
+                templateAttribute.inherit(parentTemplateAttribute);
+            }
+        }
+    }
+
+    /**
+     * Copies a BasicAttributeContext in an easier way.
+     *
+     * @param context The context to copy.
+     */
+    private void copyBasicAttributeContext(BasicAttributeContext context) {
+        Attribute parentTemplateAttribute = context.getTemplateAttribute();
+        if (parentTemplateAttribute != null) {
+            this.templateAttribute = new Attribute(parentTemplateAttribute);
+        }
+        preparer = context.preparer;
+        if (context.attributes != null && !context.attributes.isEmpty()) {
+            attributes = deepCopyAttributeMap(context.attributes);
+        }
+        copyCascadedAttributes(context);
+    }
+
+    /**
+     * Copies the cascaded attributes to the current context.
+     *
+     * @param context The context to copy from.
+     */
+    private void copyCascadedAttributes(BasicAttributeContext context) {
+        if (context.cascadedAttributes != null
+                && !context.cascadedAttributes.isEmpty()) {
+            cascadedAttributes = deepCopyAttributeMap(context.cascadedAttributes);
+        }
+    }
+
+    /**
+     * Adds missing attributes to the destination map.
+     *
+     * @param source The source attribute map.
+     * @param destination The destination attribute map.
+     * @return The destination attribute map if not null, a new one otherwise.
+     */
+    private Map<String, Attribute> addMissingAttributes(Map<String, Attribute> source,
+            Map<String, Attribute> destination) {
+        if (source != null && !source.isEmpty()) {
+            if (destination == null) {
+                destination = new HashMap<String, Attribute>();
+            }
+            for (Map.Entry<String, Attribute> entry : source.entrySet()) {
+                String key = entry.getKey();
+                Attribute destAttribute = destination.get(key);
+                if (destAttribute == null) {
+                    destination.put(key, entry.getValue());
+                } else if (destAttribute instanceof ListAttribute
+                        && entry.getValue() instanceof ListAttribute
+                        && ((ListAttribute) destAttribute).isInherit()) {
+                    ((ListAttribute) destAttribute)
+                            .inherit((ListAttribute) entry.getValue());
+                }
+            }
+        }
+
+        return destination;
+    }
+
+    /**
+     * Deep copies the attribute map, by creating clones (using copy
+     * constructors) of the attributes.
+     *
+     * @param attributes The attribute map to copy.
+     * @return The copied map.
+     */
+    private Map<String, Attribute> deepCopyAttributeMap(
+            Map<String, Attribute> attributes) {
+        Map<String, Attribute> retValue = new HashMap<String, Attribute>(attributes.size());
+        for (Map.Entry<String, Attribute> entry : attributes.entrySet()) {
+            Attribute toCopy = entry.getValue();
+            if (toCopy != null) {
+                retValue.put(entry.getKey(), toCopy.clone());
+            }
+        }
+        return retValue;
+    }
+}
diff --git a/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/CompareUtil.java b/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/CompareUtil.java
new file mode 100644
index 000000000..a3cce93d1
--- /dev/null
+++ b/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/CompareUtil.java
@@ -0,0 +1,67 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles;
+
+/**
+ * Utilities to work with comparation between objects.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public final class CompareUtil {
+
+    /**
+     * Private constructor to avoid instantiation.
+     */
+    private CompareUtil() { }
+
+    /**
+     * Checks if two objects (eventually null) are the same. They are considered the same
+     * even if they are both null.
+     *
+     * @param obj1 The first object to check.
+     * @param obj2 The second object to check.
+     * @return <code>true</code> if the objects are the same.
+     * @since 2.2.0
+     */
+    public static boolean nullSafeEquals(Object obj1, Object obj2) {
+        if (obj1 != null) {
+            return obj1.equals(obj2);
+        }
+        return obj2 == null;
+    }
+
+    /**
+     * Returns <code>0</code> if the object is null, the hash code of the object
+     * otherwise.
+     *
+     * @param obj The object from which the hash code must be calculated..
+     * @return The hash code.
+     * @since 2.2.0
+     */
+    public static int nullSafeHashCode(Object obj) {
+        if (obj != null) {
+            return obj.hashCode();
+        }
+        return 0;
+    }
+}
diff --git a/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/Definition.java b/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/Definition.java
new file mode 100644
index 000000000..8584b2cfd
--- /dev/null
+++ b/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/Definition.java
@@ -0,0 +1,162 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles;
+
+import static org.apache.tiles.CompareUtil.*;
+
+import java.util.Map;
+
+/**
+ * A definition, i.e. a template with (completely or not) filled attributes.
+ * Attributes of a template can be defined with the help of this class.<br>
+ * It can be used as a data transfer object used for registering new
+ * definitions with the Container.
+ *
+ * @since Tiles 2.0
+ * @version $Rev$ $Date$
+ */
+public class Definition extends BasicAttributeContext {
+    /**
+     * Extends attribute value.
+     */
+    protected String inherit;
+    /**
+     * Definition name.
+     */
+    protected String name = null;
+
+    /**
+     * Constructor.
+     */
+    public Definition() {
+    }
+
+    /**
+     * Copy Constructor.
+     * Create a new definition initialized with parent definition.
+     * Do a shallow copy : attributes are shared between copies, but not the Map
+     * containing attributes.
+     *
+     * @param definition The definition to copy.
+     */
+    public Definition(Definition definition) {
+        super(definition);
+        this.name = definition.name;
+        this.inherit = definition.inherit;
+    }
+
+    /**
+     * Constructor.
+     * @param name The name of the definition.
+     * @param templateAttribute The template attribute of the definition.
+     * @param attributes The attribute map of the definition.
+     *
+     * @since 2.1.2
+     */
+    public Definition(String name, Attribute templateAttribute,
+                               Map<String, Attribute> attributes) {
+        super(attributes);
+        this.name = name;
+        this.templateAttribute = templateAttribute;
+    }
+
+    /**
+     * Access method for the name property.
+     *
+     * @return the current value of the name property
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Sets the value of the name property.
+     *
+     * @param aName the new value of the name property
+     */
+    public void setName(String aName) {
+        name = aName;
+    }
+
+    /**
+     * Set extends.
+     *
+     * @param name Name of the extended definition.
+     */
+    public void setExtends(String name) {
+        inherit = name;
+    }
+
+    /**
+     * Get extends.
+     *
+     * @return Name of the extended definition.
+     */
+    public String getExtends() {
+        return inherit;
+    }
+
+
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean equals(Object obj) {
+        Definition def = (Definition) obj;
+        return nullSafeEquals(name, def.name)
+                && nullSafeEquals(inherit, def.inherit) && super.equals(def);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int hashCode() {
+        return nullSafeHashCode(name) + nullSafeHashCode(inherit)
+                + super.hashCode();
+    }
+
+    /**
+     * Get extends flag.
+     *
+     * @return <code>true</code> if this definition extends another.
+     */
+    public boolean isExtending() {
+        return inherit != null;
+    }
+
+    /**
+     * Returns a description of the attributes.
+     *
+     * @return A string representation of the content of this definition.
+     */
+    @Override
+    public String toString() {
+        return "{name="
+            + name
+            + ", template="
+            + (templateAttribute != null ? templateAttribute.getValue() : "<null>")
+            + ", role="
+            + (templateAttribute != null ? templateAttribute.getRoles() : "<null>")
+            + ", preparerInstance="
+            + preparer
+            + ", attributes="
+            + attributes
+            + "}";
+    }
+}
diff --git a/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/Expression.java b/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/Expression.java
new file mode 100644
index 000000000..4b495af87
--- /dev/null
+++ b/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/Expression.java
@@ -0,0 +1,157 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles;
+
+import static org.apache.tiles.CompareUtil.*;
+
+/**
+ * It is an expression, along with the expression language (e.g. EL, MVEL, OGNL)
+ * it is expressed with.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public class Expression {
+
+    /**
+     * The expression itself.
+     */
+    private String expression;
+
+    /**
+     * The language of the expression.
+     */
+    private String language;
+
+    /**
+     * Constructor.
+     *
+     * @param expression The expression itself.
+     * @param language The language of the expression.
+     * @since 2.2.0
+     */
+    public Expression(String expression, String language) {
+        this.expression = expression;
+        this.language = language;
+    }
+
+    /**
+     * Constructor, using the default (i.e. <code>null</code>) language.
+     *
+     * @param expression The expression itself.
+     * @since 2.2.0
+     */
+    public Expression(String expression) {
+        this(expression, null);
+    }
+
+    /**
+     * Copy constructor.
+     *
+     * @param toCopy The expression to copy.
+     * @since 2.2.0
+     */
+    public Expression(Expression toCopy) {
+        this.expression = toCopy.expression;
+        this.language = toCopy.language;
+    }
+
+    /**
+     * Creates an Expression object from a string in the form
+     * <code>LANGUAGE:EXPRESSION</code>.
+     *
+     * @param describedExpression The expression in the form
+     * <code>LANGUAGE:EXPRESSION</code>. The LANGUAGE part should be expressed
+     * only with letters and numbers.
+     * @return The created object, or <code>null</code> if the expression is null.
+     * @since 2.2.0
+     */
+    public static Expression createExpressionFromDescribedExpression(String describedExpression) {
+        if (describedExpression != null) {
+            String language = null;
+            String expression = describedExpression;
+            if (describedExpression.matches("[a-zA-Z0-9]+:.+")) {
+                language = describedExpression.substring(0, describedExpression.indexOf(':'));
+                expression = describedExpression.substring(describedExpression.indexOf(':') + 1);
+            }
+            return new Expression(expression, language);
+        }
+
+        return null;
+    }
+
+    /**
+     * Creates an Expression object from the expression and its language.
+     *
+     * @param expression The expression itself.
+     * @param language The language of the expression.
+     * @return The created object, or <code>null</code> if the expression is null.
+     * @since 2.2.0
+     */
+    public static Expression createExpression(String expression, String language) {
+        if (expression != null) {
+            return new Expression(expression, language);
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns the expression string.
+     *
+     * @return The expression itself.
+     * @since 2.2.0
+     */
+    public String getExpression() {
+        return expression;
+    }
+
+    /**
+     * Returns the language in which the expression is expressed.
+     *
+     * @return The expression language.
+     * @since 2.2.0
+     */
+    public String getLanguage() {
+        return language;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean equals(Object obj) {
+        Expression exp = (Expression) obj;
+        return nullSafeEquals(expression, exp.expression)
+                && nullSafeEquals(language, exp.language);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int hashCode() {
+        return nullSafeHashCode(expression) + nullSafeHashCode(language);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public String toString() {
+        return (language == null ? "DEFAULT" : language) + ":" + expression;
+    }
+}
diff --git a/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/ListAttribute.java b/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/ListAttribute.java
new file mode 100644
index 000000000..ae3b25aa3
--- /dev/null
+++ b/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/ListAttribute.java
@@ -0,0 +1,179 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * An attribute as a <code>List</code>.
+ * This attribute associates a name with a list. The list can be found by the
+ * property name.
+ * Elements in list are retrieved using List methods.
+ * This class is used to read configuration files.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.1.0
+ */
+public class ListAttribute extends Attribute {
+
+    /**
+     * If true, the attribute will put the elements of the attribute with the
+     * same name of the parent definition before the ones specified here. By
+     * default, it is 'false'.
+     */
+    private boolean inherit = false;
+
+    /**
+     * Constructor.
+     *
+     * @since 2.1.0
+     */
+    public ListAttribute() {
+        setValue(new ArrayList<Object>());
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param value List.
+     * @since 2.1.0
+     */
+    public ListAttribute(List<Attribute> value) {
+        setValue(value);
+    }
+
+    /**
+     * Copy constructor.
+     *
+     * @param toCopy The list attribute to copy.
+     * @since 2.1.3
+     */
+    public ListAttribute(ListAttribute toCopy) {
+        super(toCopy);
+        List<Attribute> attributesToCopy = toCopy.getValue();
+        if (attributesToCopy != null) {
+            List<Attribute> attributes = new ArrayList<Attribute>(attributesToCopy.size());
+            for (Attribute attribute : attributesToCopy) {
+                if (attribute != null) {
+                    attributes.add(attribute.clone());
+                } else {
+                    attributes.add(null);
+                }
+            }
+            setValue(attributes);
+        }
+        this.inherit = toCopy.inherit;
+    }
+
+    /**
+     * Sets the list of the attributes that are elements of this attribute.
+     *
+     * @param attributes The attributes.
+     * @since 3.0.0
+     */
+    public void setValue(List<Attribute> attributes) {
+        super.setValue(attributes);
+    }
+
+    /**
+     * Returns the list of the attributes that are elements of this attribute.
+     *
+     * @return The attributes.
+     * @since 3.0.0
+     */
+    @SuppressWarnings("unchecked")
+    @Override
+    public List<Attribute> getValue() {
+        return (List<Attribute>) super.getValue();
+    }
+
+    /**
+     * Add an element in list.
+     * We use a property to avoid rewriting a new class.
+     *
+     * @param element XmlAttribute to add.
+     * @since 2.1.0
+     */
+    public void add(Attribute element) {
+        getValue().add(element);
+    }
+
+    /**
+     * If true, the attribute will put the elements of the attribute with the
+     * same name of the parent definition before the ones specified here. By
+     * default, it is 'false'
+     *
+     * @param inherit The "inherit" value.
+     * @since 2.1.0
+     */
+    public void setInherit(boolean inherit) {
+        this.inherit = inherit;
+    }
+
+    /**
+     * If true, the attribute will put the elements of the attribute with the
+     * same name of the parent definition before the ones specified here. By
+     * default, it is 'false'
+     *
+     * @return inherit The "inherit" value.
+     * @since 2.1.0
+     */
+    public boolean isInherit() {
+        return inherit;
+    }
+
+    /**
+     * Inherits elements present in a "parent" list attribute. The elements will
+     * be put before the ones already present.
+     *
+     * @param parent The parent list attribute.
+     * @since 2.1.0
+     */
+    @SuppressWarnings("unchecked")
+    public void inherit(ListAttribute parent) {
+        List<Attribute> tempList = new ArrayList<Attribute>();
+        tempList.addAll((List<Attribute>) parent.value);
+        tempList.addAll((List<Attribute>) value);
+        setValue(tempList);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean equals(Object obj) {
+        ListAttribute attribute = (ListAttribute) obj;
+        return super.equals(attribute) && this.inherit == attribute.inherit;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public int hashCode() {
+        return super.hashCode() + Boolean.valueOf(inherit).hashCode();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public ListAttribute clone() {
+        return new ListAttribute(this);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/NoSuchContainerException.java b/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/NoSuchContainerException.java
new file mode 100644
index 000000000..631e5c0db
--- /dev/null
+++ b/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/NoSuchContainerException.java
@@ -0,0 +1,71 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles;
+
+
+/**
+ * Indicates that a keyed container has not been found.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.1.0
+ */
+public class NoSuchContainerException extends TilesException {
+
+    /**
+     * Constructor.
+     *
+     * @since 2.1.0
+     */
+    public NoSuchContainerException() {
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param message The detail message.
+     * @since 2.1.0
+     */
+    public NoSuchContainerException(String message) {
+        super(message);
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param e The exception to be wrapped.
+     * @since 2.1.0
+     */
+    public NoSuchContainerException(Throwable e) {
+        super(e);
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param message The detail message.
+     * @param e The exception to be wrapped.
+     * @since 2.1.0
+     */
+    public NoSuchContainerException(String message, Throwable e) {
+        super(message, e);
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/TilesContainer.java b/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/TilesContainer.java
new file mode 100644
index 000000000..da426a99d
--- /dev/null
+++ b/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/TilesContainer.java
@@ -0,0 +1,143 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles;
+
+import java.io.IOException;
+
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.Request;
+
+/**
+ * An encapsulation of the tiles framework.  This interface is
+ * used to expose tiles features to frameworks which leverage
+ * it as a plugin.  It can alternately be used by web applications
+ * which would like a programmatic interface.
+ *
+ * @since 2.0
+ * @version $Rev$ $Date$
+ */
+public interface TilesContainer {
+
+    /**
+     * Retrieve the containers context.
+     *
+     * @return current application context
+     */
+    ApplicationContext getApplicationContext();
+
+    /**
+     * Retrive the attribute context of the current request.
+     * @param request The request.
+     * @return map of the attributes in the current attribute context.
+     */
+    AttributeContext getAttributeContext(Request request);
+
+    /**
+     * Starts a new context, where attribute values are stored independently
+     * from others.<br>
+     * When the use of the contexts is finished, call
+     * {@link TilesContainer#endContext(Request)}
+     * @param request The request.
+     *
+     * @return The newly created context.
+     */
+    AttributeContext startContext(Request request);
+
+    /**
+     * Ends a context, where attribute values are stored independently
+     * from others.<br>
+     * It must be called after a
+     * {@link TilesContainer#startContext(Request)} call.
+     * @param request The request.
+     */
+    void endContext(Request request);
+
+    /**
+     * Renders the current context, as it is.
+     * @param request The request.
+     *
+     * @since 2.1.0
+     */
+    void renderContext(Request request);
+
+    /**
+     * Executes a preparer.
+     *
+     * @param preparer The name of the preparer to execute.
+     * @param request The request.
+     */
+    void prepare(String preparer, Request request);
+
+    /**
+     * Render the given tiles request.
+     *
+     * @param definition the current definition.
+     * @param request The request.
+     */
+    void render(String definition, Request request);
+
+    /**
+     * Renders the specified definition.
+     * @param definition The definition to render.
+     * @param request The request context.
+     */
+    void render(Definition definition, Request request);
+
+    /**
+     * Render the given Attribute.
+     *
+     * @param attribute The attribute to render.
+     * @param request The request.
+     * @throws IOException If something goes wrong during writing to the output.
+     * @since 2.1.2
+     */
+    void render(Attribute attribute, Request request)
+        throws IOException;
+
+    /**
+     * Evaluates the given attribute.
+     *
+     * @param attribute The attribute to evaluate.
+     * @param request The request.
+     * @return The evaluated object.
+     * @since 2.1.0
+     */
+    Object evaluate(Attribute attribute, Request request);
+
+    /**
+     * Returns a definition specifying its name.
+     *
+     * @param definitionName The name of the definition to find.
+     * @param request The request context.
+     * @return The definition, if found.
+     */
+    Definition getDefinition(String definitionName,
+            Request request);
+
+    /**
+     * Determine whether or not the definition exists.
+     *
+     * @param definition the name of the definition.
+     * @param request The request.
+     * @return true if the definition is found.
+     */
+    boolean isValidDefinition(String definition, Request request);
+}
diff --git a/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/TilesContainerWrapper.java b/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/TilesContainerWrapper.java
new file mode 100644
index 000000000..4a2ac7c7a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/TilesContainerWrapper.java
@@ -0,0 +1,120 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles;
+
+import java.io.IOException;
+
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.Request;
+
+/**
+ * Wraps a Tiles container to allow easy decoration.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TilesContainerWrapper implements TilesContainer {
+
+    /**
+     * The container to wrap.
+     */
+    protected TilesContainer container;
+
+    /**
+     * Constructor.
+     *
+     * @param container The container to wrap.
+     */
+    public TilesContainerWrapper(TilesContainer container) {
+        this.container = container;
+        if (container == null) {
+            throw new NullPointerException("The wrapped container must be not null");
+        }
+    }
+
+    /**
+     * Returns the wrapped container.
+     *
+     * @return The wrapped container.
+     */
+    public TilesContainer getWrappedContainer() {
+        return container;
+    }
+
+    @Override
+    public void endContext(Request request) {
+        container.endContext(request);
+    }
+
+    @Override
+    public Object evaluate(Attribute attribute, Request request) {
+        return container.evaluate(attribute, request);
+    }
+
+    @Override
+    public ApplicationContext getApplicationContext() {
+        return container.getApplicationContext();
+    }
+
+    @Override
+    public AttributeContext getAttributeContext(Request request) {
+        return container.getAttributeContext(request);
+    }
+
+    @Override
+    public Definition getDefinition(String definitionName, Request request) {
+        return container.getDefinition(definitionName, request);
+    }
+
+    @Override
+    public boolean isValidDefinition(String definition, Request request) {
+        return container.isValidDefinition(definition, request);
+    }
+
+    @Override
+    public void prepare(String preparer, Request request) {
+        container.prepare(preparer, request);
+    }
+
+    @Override
+    public void render(String definition, Request request) {
+        container.render(definition, request);
+    }
+
+    @Override
+    public void render(Definition definition, Request request) {
+        container.render(definition, request);
+    }
+
+    @Override
+    public void render(Attribute attribute, Request request) throws IOException {
+        container.render(attribute, request);
+    }
+
+    @Override
+    public void renderContext(Request request) {
+        container.renderContext(request);
+    }
+
+    @Override
+    public AttributeContext startContext(Request request) {
+        return container.startContext(request);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/TilesException.java b/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/TilesException.java
new file mode 100644
index 000000000..674584d5d
--- /dev/null
+++ b/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/TilesException.java
@@ -0,0 +1,73 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles;
+
+
+/**
+ * Root class for all Tiles-exceptions.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TilesException extends RuntimeException {
+
+    /**
+     * Constructor.
+     */
+    public TilesException() {
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param message The error or warning message.
+     */
+    public TilesException(String message) {
+        super(message);
+    }
+
+
+    /**
+     * Create a new <code>TilesException</code> wrapping an existing exception.
+     * <p/>
+     * <p>The existing exception will be embedded in the new
+     * one, and its message will become the default message for
+     * the TilesException.</p>
+     *
+     * @param e The cause to be wrapped.
+     */
+    public TilesException(Throwable e) {
+        super(e);
+    }
+
+
+    /**
+     * Create a new <code>TilesException</code> from an existing exception.
+     * <p/>
+     * <p>The existing exception will be embedded in the new
+     * one, but the new exception will have its own message.</p>
+     *
+     * @param message The detail message.
+     * @param e       The cause to be wrapped.
+     */
+    public TilesException(String message, Throwable e) {
+        super(message, e);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/access/TilesAccess.java b/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/access/TilesAccess.java
new file mode 100644
index 000000000..5df14cd14
--- /dev/null
+++ b/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/access/TilesAccess.java
@@ -0,0 +1,180 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.access;
+
+import java.util.Map;
+
+import org.apache.tiles.NoSuchContainerException;
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.Request;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Provides static access to the tiles container.
+ *
+ * @version $Rev$ $Date$
+ */
+public final class TilesAccess {
+
+    /**
+     * Name of the attribute used to store the current used container.
+     */
+    public static final String CURRENT_CONTAINER_ATTRIBUTE_NAME =
+        "org.apache.tiles.servlet.context.ServletTilesRequestContext.CURRENT_CONTAINER_KEY";
+
+    /**
+     * Constructor, private to avoid instantiation.
+     */
+    private TilesAccess() {
+    }
+
+    /**
+     * The name of the attribute to use when getting and setting the container
+     * object in a context.
+     */
+    public static final String CONTAINER_ATTRIBUTE =
+        "org.apache.tiles.CONTAINER";
+
+    /**
+     * Configures the default container to be used in the application.
+     *
+     * @param context The Tiles application context object to use.
+     * @param container The container object to set.
+     * @since 2.1.2
+     */
+    public static void setContainer(ApplicationContext context,
+            TilesContainer container) {
+        setContainer(context, container, CONTAINER_ATTRIBUTE);
+    }
+
+    /**
+     * Configures the container to be used in the application.
+     *
+     * @param context The Tiles application context object to use.
+     * @param container The container object to set.
+     * @param key The key under which the container will be stored.
+     * @since 2.1.2
+     */
+    public static void setContainer(ApplicationContext context,
+            TilesContainer container, String key) {
+        Logger log = LoggerFactory.getLogger(TilesAccess.class);
+        if (key == null) {
+            key = CONTAINER_ATTRIBUTE;
+        }
+
+        if (container == null) {
+            if (log.isInfoEnabled()) {
+                log.info("Removing TilesContext for context: " + context.getClass().getName());
+            }
+            context.getApplicationScope().remove(key);
+        } else {
+            if (log.isInfoEnabled()) {
+                log.info("Publishing TilesContext for context: " + context.getClass().getName());
+            }
+            context.getApplicationScope().put(key, container);
+        }
+    }
+
+    /**
+     * Returns default the container to be used in the application.
+     *
+     * @param context The Tiles application context object to use.
+     * @return The default container object.
+     * @since 3.0.0
+     */
+    public static TilesContainer getContainer(ApplicationContext context) {
+        return getContainer(context, CONTAINER_ATTRIBUTE);
+    }
+
+    /**
+     * Returns the container to be used in the application registered under a specific key.
+     *
+     * @param context The Tiles application context object to use.
+     * @param key The key under which the container will be stored.
+     * @return The container object.
+     * @since 3.0.0
+     */
+    public static TilesContainer getContainer(ApplicationContext context,
+            String key) {
+        if (key == null) {
+            key = CONTAINER_ATTRIBUTE;
+        }
+
+        return (TilesContainer) context.getApplicationScope().get(key);
+    }
+
+    /**
+     * Sets the current container to use in web pages.
+     *
+     * @param request The request to use.
+     * @param key The key under which the container is stored.
+     * @since 2.1.0
+     */
+    public static void setCurrentContainer(Request request,
+            String key) {
+        ApplicationContext applicationContext = request.getApplicationContext();
+        TilesContainer container = getContainer(applicationContext, key);
+        if (container != null) {
+            request.getContext("request").put(CURRENT_CONTAINER_ATTRIBUTE_NAME, container);
+        } else {
+            throw new NoSuchContainerException("The container with the key '"
+                    + key + "' cannot be found");
+        }
+    }
+
+    /**
+     * Sets the current container to use in web pages.
+     *
+     * @param request The request to use.
+     * @param container The container to use as the current container.
+     * @since 2.1.0
+     */
+    public static void setCurrentContainer(Request request,
+            TilesContainer container) {
+        if (container != null) {
+            request.getContext("request").put(CURRENT_CONTAINER_ATTRIBUTE_NAME, container);
+        } else {
+            throw new NullPointerException("The container cannot be null");
+        }
+    }
+
+    /**
+     * Returns the current container that has been set, or the default one.
+     *
+     * @param request The request to use.
+     * @return The current Tiles container to use in web pages.
+     * @since 2.1.0
+     */
+    public static TilesContainer getCurrentContainer(Request request) {
+        ApplicationContext context = request.getApplicationContext();
+        Map<String, Object> requestScope = request.getContext("request");
+        TilesContainer container = (TilesContainer) requestScope.get(CURRENT_CONTAINER_ATTRIBUTE_NAME);
+        if (container == null) {
+            container = getContainer(context);
+            requestScope.put(CURRENT_CONTAINER_ATTRIBUTE_NAME, container);
+        }
+
+        return container;
+    }
+}
diff --git a/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/access/package-info.java b/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/access/package-info.java
new file mode 100644
index 000000000..45ab9b75c
--- /dev/null
+++ b/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/access/package-info.java
@@ -0,0 +1,25 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * Tiles access package. Utility classes to access Tiles funcionality from an application.
+ */
+package org.apache.tiles.access;
+
diff --git a/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/mgmt/MutableTilesContainer.java b/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/mgmt/MutableTilesContainer.java
new file mode 100644
index 000000000..88865a58f
--- /dev/null
+++ b/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/mgmt/MutableTilesContainer.java
@@ -0,0 +1,42 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.mgmt;
+
+import org.apache.tiles.Definition;
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.request.Request;
+
+/**
+ * Defines a mutable version of the TilesContainer.
+ *
+ * @since Tiles 2.0
+ * @version $Rev$ $Date$
+ */
+public interface MutableTilesContainer extends TilesContainer {
+
+    /**
+     * Register a new definition with the container.
+     *
+     * @param definition The definition to register.
+     * @param request TODO
+     */
+    void register(Definition definition, Request request);
+}
diff --git a/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/mgmt/package-info.java b/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/mgmt/package-info.java
new file mode 100644
index 000000000..7ce089d2e
--- /dev/null
+++ b/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/mgmt/package-info.java
@@ -0,0 +1,26 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * Classes and interfaces to be used when it is needed to create Tiles definitions
+ * during the execution of the application.
+ */
+package org.apache.tiles.mgmt;
+
diff --git a/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/package-info.java b/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/package-info.java
new file mode 100644
index 000000000..3234f7dd3
--- /dev/null
+++ b/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/package-info.java
@@ -0,0 +1,387 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * The Tiles taglib and framework allows building web pages by assembling reusable
+ pieces of pages, called Tiles. A Tiles is usually a simple JSP page.
+
+ <div class="section">
+ <h2>Introduction</h2>
+
+ <p>The Tiles framework allows building pages by assembling reusable Tiles.
+ As an example, the page in the next figure can be build by assembling a
+ header, a footer, a menu and a body.</p>
+
+ <p><img src="doc-files/image001.gif" height="169" width="145" alt="doc-files/image001"></p>
+
+ <p>Each Tiles (header, menu, body, ...) is a JSP page and can itself be build
+ by assembling other Tiles.</p>
+
+ <p>Using Tiles can be compared as using Java methods: You need to define the Tiles (the method body), and then you
+ can &quot;call&quot; this body anywhere you want, passing it some parameters. In Tiles, parameters are called
+ &quot;attributes&quot; in order to avoid confusion with the request parameters.</p>
+
+ <p>The Tiles body can be a simple JSP page, a Struts action or any URI pointing
+ to a resource inside the current web site.</p>
+
+ <p>Inserting the body, or calling it, is done with the tag &lt;tiles:insert
+ ...&gt; anywhere in a JSP page. Insertion can also be done by specifying
+ a <em>definition name </em>as the path of a Struts forward or as input,
+ forward or include attributes of a Struts action.</p>
+
+ <p>Tiles bodies are used to create layouts, reusable parts, ... Tiles insertions
+ are used to insert Tiles. The same Tiles can be reused several times in
+ the same site, or even in the same page.</p>
+
+ <p>Insertion of a Tiles body can be associated to a logical name in what Tiles calls a &quot;definition&quot;. A
+ definition contains a logical name, a page used as body and some attribute values. The definition declaration
+ doesn't insert the associated Tiles body. It just associates it with the name. A definition name can be used
+ anywhere insertion of a Tiles body can occur. The associated Tiles body is then inserted with associated
+ attributes.</p>
+
+ <p>The definition declarations can be done in JSP pages or in one or more
+ centralized files. A definition can extend another one, overload some attributes,
+ add new attributes ... This allows the declaration of a &quot;master&quot; definition
+ declaring the common layout, header, menu and footer. All other definitions
+ extend this master layout thereby making it possible to change the entire
+ site look &amp; feel simply by changing the master definition. </p>
+ </div>
+ <div class="section">
+ <h2>Simple Examples</h2>
+
+ <div class="subsection1">
+ <h3>Insert a JSP page</h3>
+ <pre>&lt;tiles:insert <strong>page</strong>=&quot;/layouts/commonLayout.jsp&quot; flush=&quot;true&quot; /&gt;
+ </pre>
+ <p>This example inserts the specified page in place of the tag. The page attribute is any valid URL pointing to
+ a resource inside the current site.</p>
+ </div>
+ <div class="subsection1">
+ <a name="doc.InsertPageWithAttributes"></a>
+
+ <h3>Insert a Tiles passing some attributes</h3>
+ <pre>
+ &lt;tiles:insert page=&quot;/layouts/classicLayout.jsp&quot; flush=&amp;quot;true&quot;&gt;
+ &lt;tiles:put name=&quot;title&quot;  value=&quot;Page Title&quot; /&gt;
+ &lt;tiles:put name=&quot;header&quot; value=&quot;/common/header.jsp&quot; /&gt;
+ &lt;tiles:put name=&quot;footer&quot; value=&quot;/common/footer.jsp&quot; /&gt;
+ &lt;tiles:put name=&quot;menu&quot;   value=&quot;/common/menu.jsp&quot; /&gt;
+ &lt;tiles:put name=&quot;body&quot;   value=&quot;/tiles/mainBody.jsp&quot; /&gt;
+ &lt;/tiles:insert&gt;
+ </pre>
+ <p>This example inserts the specified page, passing it the attributes. Attributes
+ are stored in a Tiles context which is passed to the inserted pag and
+ can then be accesssed by their names.</p>
+ </div>
+ <div class="subsection1">
+ <h3>Retrieve an attribute value as String</h3>
+ <pre>
+ &lt;tiles:getAsString name=&quot;title&quot; /&gt;
+ </pre>
+ <p>This example retrieves the value of the attribute &quot;title&quot; and prints it as a String in the current
+ output stream. The method toString() is applied on the attribute value, allowing to pass any kind of object
+ as value.</p>
+ </div>
+ <div class="subsection1">
+ <h3>Insert Tiles referenced by an attribute</h3>
+ <pre>
+ &lt;tiles:insert attribute='menu' /&gt;
+ </pre>
+ <p>This inserts the Tiles referenced by the attribute &quot;menu&quot; value. The
+ specified attribute value is first retrieved from current Tiles's context,
+ and then the value is used as a page target to insert.</p>
+ </div>
+ <div class="subsection1">
+ <h3>Classic Layout </h3>
+
+ <p>This example is a layout assembling a page in the classic header-footer-menu-body
+ fashion.</p>
+ <pre>
+ &lt;%@ taglib uri=&quot;http://tiles.apache.org/tags-tiles&quot; prefix=&quot;tiles&quot; %&gt;
+ &lt;HTML&gt;
+ &lt;HEAD&gt;
+ &lt;link rel=&quot;stylesheet&quot; href=&quot;&lt;%=request.getContextPath()%&gt;/layouts/stylesheet.css&quot;
+ type=&quot;text/css&quot;/&gt;
+ &lt;title&gt;&lt;tiles:getAsString name=&quot;title&quot;/&gt;&lt;/title&gt;
+ &lt;/HEAD&gt;
+ &lt;body&gt;
+ &lt;table border=&quot;0&quot; width=&quot;100%&quot; cellspacing=&quot;5&quot;&gt;
+ &lt;tr&gt;
+ &lt;td colspan=&quot;2&quot;&gt;&lt;tiles:insert attribute=&quot;header&quot; /&gt;&lt;/td&gt;
+ &lt;/tr&gt;
+ &lt;tr&gt;
+ &lt;td width=&quot;140&quot; valign=&quot;top&quot;&gt;
+ &lt;tiles:insert attribute='menu' /&gt;
+ &lt;/td&gt;
+ &lt;td valign=&quot;top&quot;  align=&quot;left&quot;&gt;
+ &lt;tiles:insert attribute='body' /&gt;
+ &lt;/td&gt;
+ &lt;/tr&gt;
+ &lt;tr&gt;
+ &lt;td colspan=&quot;2&quot;&gt;
+ &lt;tiles:insert attribute=&quot;footer&quot; /&gt;
+ &lt;/td&gt;
+ &lt;/tr&gt;
+ &lt;/table&gt;
+ &lt;/body&gt;
+ &lt;/html&gt;
+ </pre>
+ <p>The layout is declared in a JSP page (ex: /layouts/classicLayout.jsp).
+ It can be used in conjunction with the tag described in &quot;<a href="#doc.InsertPageWithAttributes">Insert
+ a page passing some attributes</a>&quot;. </p>
+ </div>
+ </div>
+ <div class="section">
+ <h2>Definitions</h2>
+
+ <p>A definition associates a logical name with the URL of a Tiles to be inserted
+ and some attribute values. A definition doesn't insert the Tiles. This is
+ done later using the definition name. A definition name can be inserted
+ as often as you want in your site, making it easy to reuse a Tiles. </p>
+
+ <p>A definition can extend another definition and overload some attributes
+ or add new ones. This makes easy factorization of definitions differing
+ by some attributes. For example, you can define a master definition declaring
+ the main header, menu, footer, and a default title. Then let each of your
+ page definitions extend this master definition and overload the title and
+ the body.</p>
+
+ <p>Definitions can be declared in a JSP page, or in one or more centralized
+ files. To enable the definitions from centralized files, you need to initialize
+ the &quot;definitions factory&amp;&amp;quot; which will parse the definitions from the files
+ and provide them to the Tiles framework.</p>
+
+ <div class="subsection1">
+ <h3>Enabling Definition Factory</h3>
+
+ <p>To enable Tiles definitions described in one or more files, you need to write these files and to initialize the
+ definition factory. </p>
+
+ <p>Initialization is different depending on the Struts version you use,
+ or if you do not use Struts at all.</p>
+
+ <div class="subsection2">
+ <h4>Struts1.1</h4>
+
+ <p>Use the Tiles plug-in to enable Tiles definitions. This plug-in creates
+ the definition factory and passese it a configuration object populated
+ with parameters. Parameters can be specified in the web.xml file or
+ as plug-in parameters. The plug-in first reads parameters from web.xml,
+ and then overloads them with the ones found in the plug-in. All parameters
+ are optional and can be omitted. The plug-in should be declared in each
+ struts-config file:</p>
+ <pre>
+ &lt;plug-in className=&amp;&amp;quot;org.apache.struts.tiles.TilesPlugin&amp;&amp;quot; &gt;
+ &lt;set-property property=&amp;&amp;quot;definitions-config&amp;&amp;quot;
+ value=&amp;&amp;quot;/WEB-INF/tiles-defs.xml,
+ /WEB-INF/tiles-tests-defs.xml,/WEB-INF/tiles-tutorial-defs.xml,
+ /WEB-INF/tiles-examples-defs.xml&amp;&amp;quot; /&gt;
+ &lt;set-property property=&amp;&amp;quot;moduleAware&amp;&amp;quot; value=&amp;&amp;quot;true&amp;&amp;quot; /&gt;
+ &lt;set-property
+ property=&amp;&amp;quot;org.apache.tiles.definition.digester.DigesterDefinitionsReader.PARSER_VALIDATE&amp;&amp;quot;
+ value=&amp;&amp;quot;true&amp;&amp;quot; /&gt;
+ &lt;/plug-in&gt;
+ </pre>
+ <ul>
+ <li>definitions-config: (optional)
+ <ul>
+ <li>Specify configuration file names. There can be several comma separated file names (default: ?? )
+ </li>
+ </ul>
+ </li>
+ <li>org.apache.tiles.definition.digester.DigesterDefinitionsReader.PARSER_VALIDATE: (optional)
+ <ul>
+ <li>Specify if XML parser should validate the Tiles configuration
+ file
+ <ul>
+ <li>true : validate. DTD should be specified in file header (default)</li>
+ <li>false : no validation</li>
+
+ </ul>
+ </li>
+ </ul>
+ </li>
+
+ <li>moduleAware: (optional)
+ <ul>
+ <li>Specify if the Tiles definition factory is module aware. If true (default),
+ there will be one factory for each Struts module.
+ If false, there will be one common factory for all module. In this later case,
+ it is still needed to declare one plugin per module. The factory will be
+ initialized with parameters found in the first initialized plugin (generally the
+ one associated with the default module).
+ <ul>
+ <li>true : Tiles framework is module aware</li>
+ <li>false :Tiles framework has one single factoy shared among modules (default)</li>
+ </ul>
+ </li>
+ </ul>
+ </li>
+
+ <li>tilesUtilImplClassname: (optional - for advanced user)
+ <ul>
+ <li>Specify The classname of the TilesUtil implementation to use. The specified class should
+ be a subclass of TilesUtilStrutsImpl. This option disable the moduleAware option.
+ <br>Specifying &amp;&amp;&quot;TilesUtilStrutsImpl&amp;&amp;&quot; is equivalent to moduleAware =
+ false.
+ <br>Specifying &amp;&amp;&quot;TilesUtilStrutsModuleImpl&amp;&amp;&quot; is equivalent to moduleAware
+ = true.
+ This option is taken into account only once, when it is first encountered. To avoid problems,
+ it is advice to specify the same values in all TilesPlugin declaration.
+ </li>
+ </ul>
+ </li>
+
+ </ul>
+ <p>The TilesPlugin class creates one definition factory for each struts module.
+ </p>
+
+ <p>
+ If the flag moduleAware is false, only one shared factory is created for all modules.
+ In this later case, the factory is initialized with parameters found in the first plugin.
+ The plugins should be declared in all modules, and the moduleAware flag should be
+ the same for the entire application.</p>
+
+ <p>
+ Paths found in Tiles definitions are relative to the main context.</p>
+
+ <p>You don't need to specify a TilesRequestProcessor, this is automatically
+ done by the plug-in. If, however, you want to specify your own RequestProcessor,
+ it should extend the TilesRequestProcessor. The plug-in checks this
+ constraint.</p>
+ </div>
+ <div class="subsection2">
+ <h4>Struts1.0.x</h4>
+
+ <p>You need to use a special servlet extending the Struts servlet. This is specified in the web.xml file of your
+ application:</p>
+ <pre>
+ &lt;servlet&gt;
+ &lt;servlet-name&gt;action&lt;/servlet-name&gt;
+ &lt;servlet-class&gt;org.apache.tiles.web.startup.TilesServlet&lt;/servlet-class&gt;
+ &lt;!-- Tiles Servlet parameter
+ Specify configuration file names. There can be several comma
+ separated file names
+ --&gt;
+ &lt;init-param&gt;
+ &lt;param-name&gt;definitions-config&lt;/param-name&gt;
+ &lt;param-value&gt;/WEB-INF/tiles-defs.xml&lt;/param-value&gt;
+ &lt;/init-param&gt;
+ &lt;!-- Tiles Servlet parameter
+ Specify if XML parser should validate the Tiles configuration file(s).
+ true : validate. DTD should be specified in file header.
+ false : no validation
+ --&gt;
+ &lt;init-param&gt;
+ &lt;param-name&gt;org.apache.tiles.definition.digester.DigesterDefinitionsReader.PARSER_VALIDATE&lt;/param-name&gt;
+ &lt;param-value&gt;true&lt;/param-value&gt;
+ &lt;/init-param&gt;
+ ...
+ &lt;/servlet&gt;
+ </pre>
+ </div>
+ <div class="subsection2">
+ <h4>Without Struts</h4>
+
+ <p>Tiles can be used without Struts. To initialize the definition factory, you can use the provided servlet. Declare
+ it in the web.xml file of your application:</p>
+ <pre>
+ &lt;servlet&gt;
+ &lt;servlet-name&gt;action&lt;/servlet-name&gt;
+ &lt;servlet-class&gt;org.apache.struts.tiles.TilesServlet&lt;/servlet-class&gt;
+
+
+ &lt;init-param&gt;
+ &lt;param-name&gt;definitions-config&lt;/param-name&gt;
+ &lt;param-value&gt;/WEB-INF/tiles-defs.xml&lt;/param-value&gt;
+ &lt;/init-param&gt;
+ &lt;init-param&gt;
+ &lt;param-name&gt;org.apache.tiles.definition.digester.DigesterDefinitionsReader.PARSER_VALIDATE&lt;/param-name&gt;
+ &lt;param-value&gt;true&lt;/param-value&gt;
+ &lt;/init-param&gt;
+ ...
+ </pre>
+ <p>The parameters are the same as for Struts1.1 or 1.0.</p>
+ </div>
+ </div>
+ <div class="subsection1">
+ <h3>Definition File Syntax</h3>
+
+ <p>The definition file syntax can be found in the
+ <a href="http://tiles.apache.org/dtds/tiles-config_2_0.dtd">tiles-config_2_0.dtd file</a>.
+ </p>
+
+ <p>Following is a simple example:</p>
+ <pre>
+ &lt;!DOCTYPE tiles-definitions PUBLIC
+ &amp;&amp;quot;-//Apache Software Foundation//DTD Tiles Configuration//EN&amp;&amp;quot;
+ &amp;&amp;quot;http://tiles.apache.org/dtds/tiles-config_2_0.dtd&amp;&amp;quot;&gt;
+
+ &lt;!-- Definitions for Tiles documentation   --&gt;
+ &lt;tiles-definitions&gt;
+
+ &lt;!-- ========================================================== --&gt;
+ &lt;!-- Master definition                                          --&gt;
+ &lt;!-- ========================================================== --&gt;
+ &lt;!-- Main page layout used as a root for other page definitions --&gt;
+
+ &lt;definition name=&amp;&amp;quot;site.mainLayout&amp;&amp;quot;
+   template=&amp;&amp;quot;/layouts/classicLayout.jsp&amp;&amp;quot;&gt;
+ &lt;put name=&amp;&amp;quot;title&amp;&amp;quot;  value=&amp;&amp;quot;Tiles Blank Site&amp;&amp;quot; /&gt;
+ &lt;put name=&amp;&amp;quot;header&amp;&amp;quot; value=&amp;&amp;quot;/tiles/common/header.jsp&amp;&amp;quot; /&gt;
+ &lt;put name=&amp;&amp;quot;menu&amp;&amp;quot;   value=&amp;&amp;quot;site.menu.bar&amp;&amp;quot; /&gt;
+ &lt;put name=&amp;&amp;quot;footer&amp;&amp;quot; value=&amp;&amp;quot;/tiles/common/footer.jsp&amp;&amp;quot; /&gt;
+ &lt;put name=&amp;&amp;quot;body&amp;&amp;quot;   value=&amp;&amp;quot;/tiles/body.jsp&amp;&amp;quot; /&gt;
+ &lt;/definition&gt;
+
+ &lt;!-- ========================================================== --&gt;
+ &lt;!-- Index page definition                                      --&gt;
+ &lt;!-- ========================================================== --&gt;
+ &lt;!-- This definition inherits from the main definition.
+ It overloads the page title and the body used.
+ Use the same mechanism to define new pages sharing common
+ properties (here header, menu, footer, layout)
+ --&gt;
+
+ &lt;definition name=&amp;&amp;quot;site.index.page&amp;&amp;quot;
+   extends=&amp;&amp;quot;site.mainLayout&amp;&amp;quot; &gt;
+ &lt;put name=&amp;&amp;quot;title&amp;&amp;quot;  value=&amp;&amp;quot;Tiles Blank Site Index&amp;&amp;quot; /&gt;
+ &lt;put name=&amp;&amp;quot;body&amp;&amp;quot;   value=&amp;&amp;quot;/tiles/body.jsp&amp;&amp;quot; /&gt;
+ &lt;/definition&gt;
+
+ &lt;/tiles-definition&gt;
+ </pre>
+ </div>
+ <div class="subsection1">
+ <h3>Debugging</h3>
+
+ <p>To debug a page made of Tiles, you can use following advices:</p>
+ <ul>
+ <li>Check each Tiles separatly. Try to access nested Tiles directly to test
+ if thes work properly.
+ </li>
+ <li>Enable Tiles logging. See the commons-logging package help.</li>
+ </ul>
+ </div>
+ </div>
+
+ */
+package org.apache.tiles;
+
diff --git a/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/preparer/PreparerException.java b/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/preparer/PreparerException.java
new file mode 100644
index 000000000..e5188433a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/preparer/PreparerException.java
@@ -0,0 +1,71 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.preparer;
+
+import org.apache.tiles.TilesException;
+
+
+/**
+ * <p>
+ * Thrown when an exception occurs while processing
+ * a prepare request.
+ * </p>
+ *
+ * @since Tiles 2.0
+ * @version $Rev$ $Date$
+ */
+public class PreparerException extends TilesException {
+
+    /**
+     * Constructor.
+     */
+    public PreparerException() {
+        super();
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param e The cause exception.
+     */
+    public PreparerException(Throwable e) {
+        super(e);
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param message The message to include.
+     */
+    public PreparerException(String message) {
+        super(message);
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param message The message to include.
+     * @param e The cause exception.
+     */
+    public PreparerException(String message, Throwable e) {
+        super(message, e);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/preparer/ViewPreparer.java b/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/preparer/ViewPreparer.java
new file mode 100644
index 000000000..00f7743ea
--- /dev/null
+++ b/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/preparer/ViewPreparer.java
@@ -0,0 +1,58 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.preparer;
+
+import org.apache.tiles.AttributeContext;
+import org.apache.tiles.request.Request;
+
+/**
+ * <p>
+ * Executed prior to rendering a view.
+ * </p>
+ *
+ * <p>
+ * A view preparer is typically used to provide last minute
+ * translations of the data within the attribute context.
+ * A preparer is not intended to replace the controller within an
+ * MVC architecture.
+ * </p>
+ *
+ * See
+ * <ul>
+ * <li>&lt;insert&gt;</li>
+ * <li>&lt;definition&gt;</li>
+ * </ul>>
+ *
+ * @version $Rev$ $Date$
+ */
+public interface ViewPreparer {
+
+    /**
+     * Method associated to a tile and called immediately before the tile
+     * is included.
+     *
+     * @param tilesContext     Current tiles application context.
+     * @param attributeContext Current tile context.
+     * @throws PreparerException If something goes wrong during execution.
+     */
+    void execute(Request tilesContext,
+        AttributeContext attributeContext);
+}
diff --git a/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/preparer/package-info.java b/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/preparer/package-info.java
new file mode 100644
index 000000000..e4533e28a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-api/src/main/java/org/apache/tiles/preparer/package-info.java
@@ -0,0 +1,28 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * "View preparers" are objects that allows the "preparation" of a Tiles artifact
+ * (definition, template or attribute) before it is rendered.<br>
+ * It is useful, for example, when a view item should be built and stored in a
+ * particular context (e.g. a menu) and then rendered.
+ */
+package org.apache.tiles.preparer;
+
diff --git a/Java-base/tiles/src/tiles-api/src/main/resources/LICENSE.txt b/Java-base/tiles/src/tiles-api/src/main/resources/LICENSE.txt
new file mode 100644
index 000000000..d64569567
--- /dev/null
+++ b/Java-base/tiles/src/tiles-api/src/main/resources/LICENSE.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/Java-base/tiles/src/tiles-api/src/main/resources/NOTICE.txt b/Java-base/tiles/src/tiles-api/src/main/resources/NOTICE.txt
new file mode 100644
index 000000000..1f13ff856
--- /dev/null
+++ b/Java-base/tiles/src/tiles-api/src/main/resources/NOTICE.txt
@@ -0,0 +1,6 @@
+   Apache Tiles
+   Copyright 1999-2009 The Apache Software Foundation
+
+   This product includes software developed at
+   The Apache Software Foundation (http://www.apache.org/).
+
diff --git a/Java-base/tiles/src/tiles-api/src/site/site.xml b/Java-base/tiles/src/tiles-api/src/site/site.xml
new file mode 100644
index 000000000..beaec78a7
--- /dev/null
+++ b/Java-base/tiles/src/tiles-api/src/site/site.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<project name="Apache Tiles - API">
+     <skin>
+        <groupId>org.apache.maven.skins</groupId>
+        <artifactId>maven-fluido-skin</artifactId>
+        <version>1.3.0</version>
+     </skin>
+     <custom>
+        <fluidoSkin>
+        <topBarEnabled>true</topBarEnabled>
+        <sideBarEnabled>false</sideBarEnabled>
+        <searchEnabled>true</searchEnabled>
+        <gitHub>
+            <projectId>apache/tiles</projectId>
+            <ribbonOrientation>right</ribbonOrientation>
+            <ribbonColor>darkblue</ribbonColor>
+        </gitHub>
+        </fluidoSkin>
+     </custom>
+    <bannerLeft>
+        <name>Apache Tiles&#8482;</name>
+        <src>http://tiles.apache.org/images/logo.png</src>
+        <href>http://tiles.apache.org</href>
+    </bannerLeft>
+    <bannerRight>
+        <name>Apache Software Foundation</name>
+        <src>http://struts.apache.org/images/asf-logo.gif</src>
+        <href>http://www.apache.org</href>
+    </bannerRight>
+    <body>
+
+        <menu name="Apache Tiles&#8482;">
+            <item
+                   name="Welcome"
+                   href="../../index.html"/>
+            <item
+                    name="Tiles 3.0.x"
+                    href="../../framework/index.html"/>
+            <item
+                    name="Autotag 1.0.x"
+                    href="../../tiles-autotag/index.html"/>
+            <item
+                    name="Request 1.0.x"
+                    href="../../tiles-request/index.html"/>
+            <item
+                   name="Security bulletins"
+                   href="../security/index.html"/>
+            <item
+                   name="Download"
+                   href="http://tiles.apache.org/download.html"/>
+        </menu>
+
+        <menu ref="modules" />
+        <menu ref="reports" />
+
+        <footer>
+            <div class="row span12">
+                Apache Tiles, Tiles, Apache, the Apache feather logo, and the Apache Tiles
+                project logos are trademarks of The Apache Software Foundation.
+            </div>
+        </footer>
+    </body>
+</project>
diff --git a/Java-base/tiles/src/tiles-api/src/test/java/org/apache/tiles/AttributeTest.java b/Java-base/tiles/src/tiles-api/src/test/java/org/apache/tiles/AttributeTest.java
new file mode 100644
index 000000000..68105f315
--- /dev/null
+++ b/Java-base/tiles/src/tiles-api/src/test/java/org/apache/tiles/AttributeTest.java
@@ -0,0 +1,292 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles;
+
+import static org.apache.tiles.CompareUtil.*;
+import static org.easymock.EasyMock.*;
+import static org.easymock.classextension.EasyMock.*;
+import static org.junit.Assert.*;
+
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.apache.tiles.request.Request;
+import org.junit.Test;
+
+/**
+ * Tests {@link Attribute}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class AttributeTest {
+
+
+    /**
+     * Tests {@link Attribute#createTemplateAttribute(String)}.
+     */
+    @Test
+    public void testCreateTemplateAttribute1() {
+        Attribute attribute = Attribute.createTemplateAttribute("/my/template.jsp");
+        assertEquals("/my/template.jsp", attribute.getValue());
+        assertEquals("template", attribute.getRenderer());
+    }
+
+    /**
+     * Tests {@link Attribute#createTemplateAttributeWithExpression(String)}.
+     */
+    @Test
+    public void testCreateTemplateAttribute2() {
+        Attribute attribute = Attribute.createTemplateAttributeWithExpression("my.expression");
+        assertEquals("template", attribute.getRenderer());
+        assertEquals("my.expression", attribute.getExpressionObject().getExpression());
+        assertNull(attribute.getExpressionObject().getLanguage());
+    }
+
+    /**
+     * Tests {@link Attribute#Attribute()}.
+     */
+    @Test
+    public void testAttribute() {
+        Attribute attribute = new Attribute();
+        assertNull(attribute.getValue());
+    }
+
+    /**
+     * Tests {@link Attribute#Attribute(Object)}.
+     */
+    @Test
+    public void testAttributeObject() {
+        Attribute attribute = new Attribute("my.value");
+        assertEquals("my.value", attribute.getValue());
+        assertNull(attribute.getRenderer());
+    }
+
+    /**
+     * Tests {@link Attribute#Attribute(Object, String)}.
+     */
+    @Test
+    public void testAttributeObjectString() {
+        Attribute attribute = new Attribute("my.value", "role1,role2");
+        assertEquals("my.value", attribute.getValue());
+        assertNull(attribute.getRenderer());
+        Set<String> roles = new HashSet<String>();
+        roles.add("role1");
+        roles.add("role2");
+        assertEquals(roles, attribute.getRoles());
+    }
+
+    /**
+     * Tests {@link Attribute#Attribute(Object, Expression, String, String)}.
+     */
+    @Test
+    public void testAttributeComplete() {
+        Expression expression = new Expression("my.expression", "MYLANG");
+        Attribute attribute = new Attribute("my.value", expression, "role1,role2", "myrenderer");
+        assertEquals("my.value", attribute.getValue());
+        assertEquals("myrenderer", attribute.getRenderer());
+        Set<String> roles = new HashSet<String>();
+        roles.add("role1");
+        roles.add("role2");
+        assertEquals(roles, attribute.getRoles());
+        assertEquals("my.expression", attribute.getExpressionObject().getExpression());
+        assertEquals("MYLANG", attribute.getExpressionObject().getLanguage());
+    }
+
+    /**
+     * Tests {@link Attribute#Attribute(Attribute)}.
+     */
+    @Test
+    public void testAttributeCopy() {
+        Expression expression = new Expression("my.expression", "MYLANG");
+        Attribute attribute = new Attribute("my.value", expression, "role1,role2", "myrenderer");
+        attribute = new Attribute(attribute);
+        assertEquals("my.value", attribute.getValue());
+        assertEquals("myrenderer", attribute.getRenderer());
+        Set<String> roles = new HashSet<String>();
+        roles.add("role1");
+        roles.add("role2");
+        assertEquals(roles, attribute.getRoles());
+        assertEquals("my.expression", attribute.getExpressionObject().getExpression());
+        assertEquals("MYLANG", attribute.getExpressionObject().getLanguage());
+
+        attribute = new Attribute("my.value", null, "role1,role2", "myrenderer");
+        attribute = new Attribute(attribute);
+        assertEquals("my.value", attribute.getValue());
+        assertEquals("myrenderer", attribute.getRenderer());
+        roles = new HashSet<String>();
+        roles.add("role1");
+        roles.add("role2");
+        assertEquals(roles, attribute.getRoles());
+        assertNull(attribute.getExpressionObject());
+    }
+
+    /**
+     * Tests {@link Attribute#equals(Object)}.
+     */
+    @Test
+    public void testEquals() {
+        Expression expression = new Expression("my.expression", "MYLANG");
+        Attribute attribute = new Attribute("my.value", expression, "role1,role2", "myrenderer");
+        Attribute attribute2 = new Attribute(attribute);
+        assertTrue(attribute.equals(attribute2));
+        attribute2.setRenderer("anotherRenderer");
+        assertFalse(attribute.equals(attribute2));
+        attribute2 = new Attribute(attribute);
+        attribute2.setRole("otherrole");
+        assertFalse(attribute.equals(attribute2));
+        attribute2 = new Attribute(attribute);
+        attribute2.setExpressionObject(new Expression("another.expression", "MYLANG"));
+        assertFalse(attribute.equals(attribute2));
+        attribute2 = new Attribute(attribute);
+        attribute2.setValue("anothervalue");
+        assertFalse(attribute.equals(attribute2));
+    }
+
+    /**
+     * Tests {@link Attribute#getRole()} and {@link Attribute#setRole(String)}.
+     */
+    @Test
+    public void testGetRole() {
+        Attribute attribute = new Attribute("my.value");
+        assertNull(attribute.getRole());
+        Set<String> roles = new LinkedHashSet<String>();
+        attribute.setRoles(roles);
+        assertNull(attribute.getRole());
+        roles.add("role1");
+        roles.add("role2");
+        assertEquals("role1,role2", attribute.getRole());
+    }
+
+    /**
+     * Tests {@link Attribute#hashCode()}.
+     */
+    @Test
+    public void testHashCode() {
+        Expression expression = new Expression("my.expression", "MYLANG");
+        Attribute attribute = new Attribute("my.value", expression, "role1,role2", "myrenderer");
+        Set<String> roles = new HashSet<String>();
+        roles.add("role1");
+        roles.add("role2");
+        assertEquals(nullSafeHashCode("my.value")
+                + nullSafeHashCode(expression) + nullSafeHashCode(roles)
+                + nullSafeHashCode("myrenderer"), attribute.hashCode());
+    }
+
+    /**
+     * Tests {@link Attribute#toString()}.
+     */
+    @Test
+    public void testToString() {
+        Expression expression = new Expression("my.expression", "MYLANG");
+        Attribute attribute = new Attribute("my.value", expression, "role1,role2", "myrenderer");
+        Set<String> roles = new HashSet<String>();
+        roles.add("role1");
+        roles.add("role2");
+        assertEquals("my.value", attribute.toString());
+        attribute.setValue(null);
+        assertNull(attribute.toString());
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.Attribute#inherit(org.apache.tiles.Attribute)}.
+     */
+    @Test
+    public void testInherit() {
+        Attribute attribute = new Attribute(null, (Expression) null, null, (String) null);
+        Attribute parentAttribute = new Attribute("value", Expression
+                .createExpression("expression", "language"), "role", "renderer");
+        attribute.inherit(parentAttribute);
+        assertEquals("value", attribute.getValue());
+        assertEquals("expression", attribute.getExpressionObject().getExpression());
+        assertEquals("language", attribute.getExpressionObject().getLanguage());
+        assertEquals("role", attribute.getRole());
+        assertEquals("renderer", attribute.getRenderer());
+        Expression expression = new Expression(null, "MYLANG");
+        attribute = new Attribute(null, expression, null, (String) null);
+        attribute.setRoles(new HashSet<String>());
+        attribute.inherit(parentAttribute);
+        assertEquals("value", attribute.getValue());
+        assertEquals("expression", attribute.getExpressionObject().getExpression());
+        assertEquals("language", attribute.getExpressionObject().getLanguage());
+        assertEquals("role", attribute.getRole());
+        assertEquals("renderer", attribute.getRenderer());
+    }
+
+    /**
+     * Tests {@link Attribute#clone()}.
+     */
+    @Test
+    public void testClone() {
+        Expression expression = new Expression("my.expression", "MYLANG");
+        Attribute attribute = new Attribute("my.value", expression, "role1,role2", "myrenderer");
+        attribute = attribute.clone();
+        assertEquals("my.value", attribute.getValue());
+        assertEquals("myrenderer", attribute.getRenderer());
+        Set<String> roles = new HashSet<String>();
+        roles.add("role1");
+        roles.add("role2");
+        assertEquals(roles, attribute.getRoles());
+        assertEquals("my.expression", attribute.getExpressionObject().getExpression());
+        assertEquals("MYLANG", attribute.getExpressionObject().getLanguage());
+    }
+
+    /**
+     * Tests {@link Attribute#createTemplateAttribute(String, String, String, String)}.
+     */
+    @Test
+    public void testCreateTemplateAttribute() {
+        Attribute attribute = Attribute.createTemplateAttribute("myTemplate",
+                "MYLANG:myExpression", "myType", "myRole");
+        assertEquals("myTemplate", attribute.getValue());
+        assertEquals("MYLANG", attribute.getExpressionObject().getLanguage());
+        assertEquals("myExpression", attribute.getExpressionObject().getExpression());
+        assertEquals("myType", attribute.getRenderer());
+        Set<String> roles = attribute.getRoles();
+        assertEquals(1, roles.size());
+        assertTrue(roles.contains("myRole"));
+    }
+
+    /**
+     * Tests {@link Attribute#isPermitted(Request)}.
+     */
+    @Test
+    public void testIsPermitted() {
+        Attribute attribute = new Attribute("myvalue");
+        Request requestContext = createMock(Request.class);
+        expect(requestContext.isUserInRole("first")).andReturn(Boolean.TRUE)
+                .anyTimes();
+        expect(requestContext.isUserInRole("second")).andReturn(Boolean.FALSE)
+                .anyTimes();
+        replay(requestContext);
+        assertTrue(attribute.isPermitted(requestContext));
+        Set<String> roles = new HashSet<String>();
+        roles.add("first");
+        attribute.setRoles(roles);
+        assertTrue("The role is not permitted", attribute.isPermitted(
+                requestContext));
+        roles.clear();
+        roles.add("second");
+        assertFalse("The role is not permitted", attribute.isPermitted(
+                requestContext));
+        verify(requestContext);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-api/src/test/java/org/apache/tiles/BasicAttributeContextTest.java b/Java-base/tiles/src/tiles-api/src/test/java/org/apache/tiles/BasicAttributeContextTest.java
new file mode 100644
index 000000000..32cf83636
--- /dev/null
+++ b/Java-base/tiles/src/tiles-api/src/test/java/org/apache/tiles/BasicAttributeContextTest.java
@@ -0,0 +1,800 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles;
+
+import static org.junit.Assert.*;
+import static org.easymock.EasyMock.*;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.junit.Test;
+
+/**
+ * Tests <code>BasicAttributeContext</code>.
+ *
+ * @version $Rev$ $Date$
+ */
+public class BasicAttributeContextTest {
+
+    /**
+     * Tests {@link BasicAttributeContext#BasicAttributeContext()}.
+     */
+    @Test
+    public void testBasicAttributeContext() {
+        AttributeContext context = new BasicAttributeContext();
+        assertNull("There are some spurious attributes", context
+                .getLocalAttributeNames());
+        assertNull("There are some spurious attributes", context
+                .getCascadedAttributeNames());
+    }
+
+    /**
+     * Tests {@link BasicAttributeContext#BasicAttributeContext(Map)}.
+     */
+    @Test
+    public void testBasicAttributeContextMapOfStringAttribute() {
+        Map<String, Attribute> name2attrib = new HashMap<String, Attribute>();
+        Attribute attribute = new Attribute("Value 1");
+        name2attrib.put("name1", attribute);
+        attribute = new Attribute("Value 2");
+        name2attrib.put("name2", attribute);
+        AttributeContext context = new BasicAttributeContext(name2attrib);
+        attribute = context.getAttribute("name1");
+        assertNotNull("Attribute name1 not found", attribute);
+        assertEquals("Attribute name1 has not been set correctly", "Value 1",
+                attribute.getValue());
+        attribute = context.getAttribute("name2");
+        assertNotNull("Attribute name2 not found", attribute);
+        assertEquals("Attribute name2 has not been set correctly", "Value 2",
+                attribute.getValue());
+    }
+
+    /**
+     * Tests
+     * {@link BasicAttributeContext#BasicAttributeContext(AttributeContext)}.
+     */
+    @Test
+    public void testBasicAttributeContextAttributeContext() {
+        Set<String> localAttributes = new LinkedHashSet<String>();
+        Set<String> cascadedAttributes = new LinkedHashSet<String>();
+        localAttributes.add("local1");
+        localAttributes.add("local2");
+        cascadedAttributes.add("cascaded1");
+        cascadedAttributes.add("cascaded2");
+        AttributeContext toCopy = createMock(AttributeContext.class);
+        expect(toCopy.getLocalAttributeNames()).andReturn(localAttributes);
+        expect(toCopy.getLocalAttribute("local1")).andReturn(
+                new Attribute("value1")).anyTimes();
+        expect(toCopy.getLocalAttribute("local2")).andReturn(
+                new Attribute("value2")).anyTimes();
+        expect(toCopy.getCascadedAttributeNames())
+                .andReturn(cascadedAttributes);
+        expect(toCopy.getCascadedAttribute("cascaded1")).andReturn(
+                new Attribute("value3")).anyTimes();
+        expect(toCopy.getCascadedAttribute("cascaded2")).andReturn(
+                new Attribute("value4")).anyTimes();
+        Attribute templateAttribute = new Attribute("/template.jsp", Expression
+                .createExpression("expression", null), "role1,role2",
+                "template");
+        expect(toCopy.getTemplateAttribute()).andReturn(templateAttribute);
+        Set<String> roles = new HashSet<String>();
+        roles.add("role1");
+        roles.add("role2");
+        expect(toCopy.getPreparer()).andReturn("my.preparer.Preparer");
+        replay(toCopy);
+        BasicAttributeContext context = new BasicAttributeContext(toCopy);
+        assertEquals("The template has not been set correctly",
+                "/template.jsp", context.getTemplateAttribute().getValue());
+        assertEquals("The template expression has not been set correctly",
+                "expression", context.getTemplateAttribute()
+                        .getExpressionObject().getExpression());
+        assertEquals("The roles are not the same", roles, context
+                .getTemplateAttribute().getRoles());
+        assertEquals("The preparer has not been set correctly",
+                "my.preparer.Preparer", context.getPreparer());
+        Attribute attribute = context.getLocalAttribute("local1");
+        assertNotNull("Attribute local1 not found", attribute);
+        assertEquals("Attribute local1 has not been set correctly", "value1",
+                attribute.getValue());
+        attribute = context.getLocalAttribute("local2");
+        assertNotNull("Attribute local2 not found", attribute);
+        assertEquals("Attribute local2 has not been set correctly", "value2",
+                attribute.getValue());
+        attribute = context.getCascadedAttribute("cascaded1");
+        assertNotNull("Attribute cascaded1 not found", attribute);
+        assertEquals("Attribute cascaded1 has not been set correctly",
+                "value3", attribute.getValue());
+        attribute = context.getCascadedAttribute("cascaded2");
+        assertNotNull("Attribute cascaded2 not found", attribute);
+        assertEquals("Attribute cascaded2 has not been set correctly",
+                "value4", attribute.getValue());
+    }
+
+    /**
+     * Tests
+     * {@link BasicAttributeContext#BasicAttributeContext(BasicAttributeContext)}
+     * .
+     */
+    @Test
+    public void testBasicAttributeContextBasicAttributeContext() {
+        BasicAttributeContext toCopy = new BasicAttributeContext();
+        toCopy.putAttribute("name1", new Attribute("value1"), false);
+        toCopy.putAttribute("name2", new Attribute("value2"), true);
+        Attribute templateAttribute = Attribute
+                .createTemplateAttribute("/template.jsp");
+        Set<String> roles = new HashSet<String>();
+        roles.add("role1");
+        roles.add("role2");
+        templateAttribute.setRoles(roles);
+        toCopy.setTemplateAttribute(templateAttribute);
+        toCopy.setPreparer("my.preparer.Preparer");
+        AttributeContext context = new BasicAttributeContext(toCopy);
+        assertEquals("The template has not been set correctly",
+                "/template.jsp", context.getTemplateAttribute().getValue());
+        assertEquals("The roles are not the same", roles, context
+                .getTemplateAttribute().getRoles());
+        assertEquals("The preparer has not been set correctly",
+                "my.preparer.Preparer", context.getPreparer());
+        Attribute attribute = context.getLocalAttribute("name1");
+        assertNotNull("Attribute name1 not found", attribute);
+        assertEquals("Attribute name1 has not been set correctly", "value1",
+                attribute.getValue());
+        attribute = context.getCascadedAttribute("name2");
+        assertNotNull("Attribute name2 not found", attribute);
+        assertEquals("Attribute name2 has not been set correctly", "value2",
+                attribute.getValue());
+    }
+
+    /**
+     * Tests
+     * {@link BasicAttributeContext#inheritCascadedAttributes(AttributeContext)}
+     * .
+     */
+    @Test
+    public void testInheritCascadedAttributes() {
+        AttributeContext toCopy = new BasicAttributeContext();
+        toCopy.putAttribute("name1", new Attribute("value1"), false);
+        toCopy.putAttribute("name2", new Attribute("value2"), true);
+        AttributeContext context = new BasicAttributeContext();
+        context.inheritCascadedAttributes(toCopy);
+        Attribute attribute = context.getLocalAttribute("name1");
+        assertNull("Attribute name1 found", attribute);
+        attribute = context.getCascadedAttribute("name2");
+        assertNotNull("Attribute name2 not found", attribute);
+        assertEquals("Attribute name2 has not been set correctly", "value2",
+                attribute.getValue());
+    }
+
+    /**
+     * Tests {@link BasicAttributeContext#inherit(BasicAttributeContext)}
+     * testing inheritance between {@link ListAttribute} instances.
+     */
+    @Test
+    public void testInheritListAttribute() {
+        AttributeContext toCopy = new BasicAttributeContext();
+        ListAttribute parentListAttribute = new ListAttribute();
+        Attribute first = new Attribute("first");
+        Attribute second = new Attribute("second");
+        parentListAttribute.add(first);
+        toCopy.putAttribute("list", parentListAttribute);
+        AttributeContext context = new BasicAttributeContext();
+        ListAttribute listAttribute = new ListAttribute();
+        listAttribute.setInherit(true);
+        listAttribute.add(second);
+        context.putAttribute("list", listAttribute);
+        context.inherit(toCopy);
+        ListAttribute result = (ListAttribute) context.getAttribute("list");
+        assertNotNull("The attribute must exist", result);
+        List<Attribute> value = result.getValue();
+        assertNotNull("The list must exist", value);
+        assertEquals("The size is not correct", 2, value.size());
+        assertEquals("The first element is not correct", first, value.get(0));
+        assertEquals("The second element is not correct", second, value
+                .get(1));
+
+        context = new BasicAttributeContext();
+        listAttribute = new ListAttribute();
+        listAttribute.add(second);
+        context.putAttribute("list", listAttribute);
+        context.inherit(toCopy);
+        result = (ListAttribute) context.getAttribute("list");
+        assertNotNull("The attribute must exist", result);
+        value = result.getValue();
+        assertNotNull("The list must exist", value);
+        assertEquals("The size is not correct", 1, value.size());
+        assertEquals("The second element is not correct", second, value
+                .get(0));
+    }
+
+    /**
+     * Tests
+     * {@link BasicAttributeContext#inheritCascadedAttributes(AttributeContext)}
+     * .
+     */
+    @Test
+    public void testInherit() {
+        AttributeContext toCopy = new BasicAttributeContext();
+        Attribute parentTemplateAttribute = new Attribute();
+        parentTemplateAttribute.setValue("/parent/template.jsp");
+        toCopy.setTemplateAttribute(parentTemplateAttribute);
+        toCopy.putAttribute("name1", new Attribute("value1"), true);
+        toCopy.putAttribute("name2", new Attribute("value2"), true);
+        toCopy.putAttribute("name3", new Attribute("value3"), false);
+        toCopy.putAttribute("name4", new Attribute("value4"), false);
+        AttributeContext context = new BasicAttributeContext();
+        Attribute templateAttribute = new Attribute();
+        templateAttribute.setRole("role1,role2");
+        context.setTemplateAttribute(templateAttribute);
+        context.putAttribute("name1", new Attribute("newValue1"), true);
+        context.putAttribute("name3", new Attribute("newValue3"), false);
+        context.inherit(toCopy);
+        Attribute attribute = context.getTemplateAttribute();
+        assertEquals("/parent/template.jsp", attribute.getValue());
+        assertTrue(attribute.getRoles().contains("role1"));
+        assertTrue(attribute.getRoles().contains("role2"));
+        attribute = context.getCascadedAttribute("name1");
+        assertNotNull("Attribute name1 not found", attribute);
+        assertEquals("Attribute name1 has not been set correctly", "newValue1",
+                attribute.getValue());
+        attribute = context.getCascadedAttribute("name2");
+        assertNotNull("Attribute name2 not found", attribute);
+        assertEquals("Attribute name2 has not been set correctly", "value2",
+                attribute.getValue());
+        attribute = context.getLocalAttribute("name3");
+        assertNotNull("Attribute name3 not found", attribute);
+        assertEquals("Attribute name3 has not been set correctly", "newValue3",
+                attribute.getValue());
+        attribute = context.getLocalAttribute("name4");
+        assertNotNull("Attribute name4 not found", attribute);
+        assertEquals("Attribute name4 has not been set correctly", "value4",
+                attribute.getValue());
+
+        toCopy = new BasicAttributeContext();
+        toCopy.putAttribute("name1", new Attribute("value1"), true);
+        toCopy.putAttribute("name2", new Attribute("value2"), true);
+        toCopy.putAttribute("name3", new Attribute("value3"), false);
+        toCopy.putAttribute("name4", new Attribute("value4"), false);
+        context = new BasicAttributeContext();
+        context.inherit(toCopy);
+        attribute = context.getCascadedAttribute("name1");
+        assertNotNull("Attribute name1 not found", attribute);
+        assertEquals("Attribute name1 has not been set correctly", "value1",
+                attribute.getValue());
+        attribute = context.getCascadedAttribute("name2");
+        assertNotNull("Attribute name2 not found", attribute);
+        assertEquals("Attribute name2 has not been set correctly", "value2",
+                attribute.getValue());
+        attribute = context.getLocalAttribute("name3");
+        assertNotNull("Attribute name3 not found", attribute);
+        assertEquals("Attribute name3 has not been set correctly", "value3",
+                attribute.getValue());
+        attribute = context.getLocalAttribute("name4");
+        assertNotNull("Attribute name4 not found", attribute);
+        assertEquals("Attribute name4 has not been set correctly", "value4",
+                attribute.getValue());
+    }
+
+    /**
+     * Tests
+     * {@link BasicAttributeContext#inherit(AttributeContext)}
+     * .
+     */
+    @Test
+    public void testInheritAttributeContext() {
+        AttributeContext toCopy = createMock(AttributeContext.class);
+        Attribute templateAttribute = Attribute.createTemplateAttribute("/my/template.jsp");
+        expect(toCopy.getTemplateAttribute()).andReturn(templateAttribute);
+        expect(toCopy.getPreparer()).andReturn("my.preparer");
+        Set<String> cascadedNames = new HashSet<String>();
+        cascadedNames.add("name1");
+        cascadedNames.add("name2");
+        expect(toCopy.getCascadedAttributeNames()).andReturn(cascadedNames);
+        expect(toCopy.getCascadedAttribute("name1")).andReturn(new Attribute("value1"));
+        expect(toCopy.getCascadedAttribute("name2")).andReturn(new Attribute("value2"));
+        Set<String> names = new HashSet<String>();
+        names.add("name3");
+        names.add("name4");
+        expect(toCopy.getLocalAttributeNames()).andReturn(names);
+        expect(toCopy.getLocalAttribute("name3")).andReturn(new Attribute("value3"));
+        expect(toCopy.getLocalAttribute("name4")).andReturn(new Attribute("value4"));
+
+        replay(toCopy);
+        AttributeContext context = new BasicAttributeContext();
+        context.putAttribute("name1", new Attribute("newValue1"), true);
+        context.putAttribute("name3", new Attribute("newValue3"), false);
+        context.inherit(toCopy);
+        Attribute attribute = context.getCascadedAttribute("name1");
+        assertEquals("/my/template.jsp", context.getTemplateAttribute().getValue());
+        assertEquals("my.preparer", context.getPreparer());
+        assertNotNull("Attribute name1 not found", attribute);
+        assertEquals("Attribute name1 has not been set correctly", "newValue1",
+                attribute.getValue());
+        attribute = context.getCascadedAttribute("name2");
+        assertNotNull("Attribute name2 not found", attribute);
+        assertEquals("Attribute name2 has not been set correctly", "value2",
+                attribute.getValue());
+        attribute = context.getLocalAttribute("name3");
+        assertNotNull("Attribute name3 not found", attribute);
+        assertEquals("Attribute name3 has not been set correctly", "newValue3",
+                attribute.getValue());
+        attribute = context.getLocalAttribute("name4");
+        assertNotNull("Attribute name4 not found", attribute);
+        assertEquals("Attribute name4 has not been set correctly", "value4",
+                attribute.getValue());
+        verify(toCopy);
+    }
+
+    /**
+     * Tests {@link BasicAttributeContext#inherit(AttributeContext)}
+     * testing inheritance between {@link ListAttribute} instances.
+     */
+    @Test
+    public void testInheritAttributeContextListAttribute() {
+        AttributeContext toCopy = createMock(AttributeContext.class);
+        Attribute templateAttribute = Attribute.createTemplateAttribute("/my/template.jsp");
+        expect(toCopy.getTemplateAttribute()).andReturn(templateAttribute).times(2);
+        expect(toCopy.getPreparer()).andReturn("my.preparer").times(2);
+        ListAttribute parentListAttribute = new ListAttribute();
+        Attribute first = new Attribute("first");
+        Attribute second = new Attribute("second");
+        Attribute third = new Attribute("third");
+        Attribute fourth = new Attribute("fourth");
+        parentListAttribute.add(first);
+        ListAttribute parentListAttribute2 = new ListAttribute();
+        parentListAttribute2.add(third);
+        Set<String> names = new HashSet<String>();
+        names.add("list");
+        Set<String> cascadedNames = new HashSet<String>();
+        cascadedNames.add("list2");
+        expect(toCopy.getCascadedAttributeNames()).andReturn(cascadedNames).times(2);
+        expect(toCopy.getCascadedAttribute("list2")).andReturn(parentListAttribute2).times(2);
+        expect(toCopy.getLocalAttributeNames()).andReturn(names).times(2);
+        expect(toCopy.getLocalAttribute("list")).andReturn(parentListAttribute).times(2);
+
+        replay(toCopy);
+        AttributeContext context = new BasicAttributeContext();
+        ListAttribute listAttribute = new ListAttribute();
+        listAttribute.setInherit(true);
+        listAttribute.add(second);
+        context.putAttribute("list", listAttribute, false);
+        ListAttribute listAttribute2 = new ListAttribute();
+        listAttribute2.setInherit(true);
+        listAttribute2.add(fourth);
+        context.putAttribute("list2", listAttribute2, true);
+        context.inherit(toCopy);
+        ListAttribute result = (ListAttribute) context.getAttribute("list");
+        assertNotNull("The attribute must exist", result);
+        List<Attribute> value = result.getValue();
+        assertNotNull("The list must exist", value);
+        assertEquals("The size is not correct", 2, value.size());
+        assertEquals("The first element is not correct", first, value.get(0));
+        assertEquals("The second element is not correct", second, value
+                .get(1));
+        result = (ListAttribute) context.getAttribute("list2");
+        assertNotNull("The attribute must exist", result);
+        value = result.getValue();
+        assertNotNull("The list must exist", value);
+        assertEquals("The size is not correct", 2, value.size());
+        assertEquals("The first element is not correct", third, value.get(0));
+        assertEquals("The second element is not correct", fourth, value
+                .get(1));
+
+        context = new BasicAttributeContext();
+        listAttribute = new ListAttribute();
+        listAttribute.add(second);
+        context.putAttribute("list", listAttribute);
+        context.inherit(toCopy);
+        result = (ListAttribute) context.getAttribute("list");
+        assertNotNull("The attribute must exist", result);
+        value = result.getValue();
+        assertNotNull("The list must exist", value);
+        assertEquals("The size is not correct", 1, value.size());
+        assertEquals("The second element is not correct", second, value
+                .get(0));
+        verify(toCopy);
+    }
+
+    /**
+     * Tests {@link BasicAttributeContext#addAll(Map)}.
+     */
+    @Test
+    public void testAddAll() {
+        AttributeContext context = new BasicAttributeContext();
+        Map<String, Attribute> name2attrib = new HashMap<String, Attribute>();
+        Attribute attribute = new Attribute("Value 1");
+        name2attrib.put("name1", attribute);
+        attribute = new Attribute("Value 2");
+        name2attrib.put("name2", attribute);
+        context.addAll(name2attrib);
+        attribute = context.getAttribute("name1");
+        assertNotNull("Attribute name1 not found", attribute);
+        assertEquals("Attribute name1 has not been set correctly", "Value 1",
+                attribute.getValue());
+        attribute = context.getAttribute("name2");
+        assertNotNull("Attribute name2 not found", attribute);
+        assertEquals("Attribute name2 has not been set correctly", "Value 2",
+                attribute.getValue());
+
+        context.addAll(null);
+        attribute = context.getAttribute("name1");
+        assertNotNull("Attribute name1 not found", attribute);
+        assertEquals("Attribute name1 has not been set correctly", "Value 1",
+                attribute.getValue());
+        attribute = context.getAttribute("name2");
+        assertNotNull("Attribute name2 not found", attribute);
+        assertEquals("Attribute name2 has not been set correctly", "Value 2",
+                attribute.getValue());
+
+        name2attrib = new HashMap<String, Attribute>();
+        name2attrib.put("name3", new Attribute("Value 3"));
+        context.addAll(name2attrib);
+        attribute = context.getAttribute("name1");
+        assertNotNull("Attribute name1 not found", attribute);
+        assertEquals("Attribute name1 has not been set correctly", "Value 1",
+                attribute.getValue());
+        attribute = context.getAttribute("name2");
+        assertNotNull("Attribute name2 not found", attribute);
+        assertEquals("Attribute name2 has not been set correctly", "Value 2",
+                attribute.getValue());
+        attribute = context.getAttribute("name3");
+        assertNotNull("Attribute name3 not found", attribute);
+        assertEquals("Attribute name3 has not been set correctly", "Value 3",
+                attribute.getValue());
+    }
+
+    /**
+     * Tests {@link BasicAttributeContext#addMissing(Map)}.
+     */
+    @Test
+    public void testAddMissing() {
+        Map<String, Attribute> name2attrib = new HashMap<String, Attribute>();
+        Attribute attribute = new Attribute("Value 1");
+        name2attrib.put("name1", attribute);
+        attribute = new Attribute("Value 2");
+        name2attrib.put("name2", attribute);
+        AttributeContext context = new BasicAttributeContext(name2attrib);
+        name2attrib.remove("name2");
+        name2attrib.put("name1", new Attribute("Value 1a"));
+        name2attrib.put("name3", new Attribute("Value 3"));
+        context.addMissing(name2attrib);
+        attribute = context.getAttribute("name1");
+        assertNotNull("Attribute name1 not found", attribute);
+        assertEquals("Attribute name1 has not been set correctly", "Value 1",
+                attribute.getValue());
+        attribute = context.getAttribute("name2");
+        assertNotNull("Attribute name2 not found", attribute);
+        assertEquals("Attribute name2 has not been set correctly", "Value 2",
+                attribute.getValue());
+        attribute = context.getAttribute("name3");
+        assertNotNull("Attribute name3 not found", attribute);
+        assertEquals("Attribute name3 has not been set correctly", "Value 3",
+                attribute.getValue());
+
+        context.addMissing(null);
+        attribute = context.getAttribute("name1");
+        assertNotNull("Attribute name1 not found", attribute);
+        assertEquals("Attribute name1 has not been set correctly", "Value 1",
+                attribute.getValue());
+        attribute = context.getAttribute("name2");
+        assertNotNull("Attribute name2 not found", attribute);
+        assertEquals("Attribute name2 has not been set correctly", "Value 2",
+                attribute.getValue());
+        attribute = context.getAttribute("name3");
+        assertNotNull("Attribute name3 not found", attribute);
+        assertEquals("Attribute name3 has not been set correctly", "Value 3",
+                attribute.getValue());
+
+        context = new BasicAttributeContext();
+        name2attrib = new HashMap<String, Attribute>();
+        name2attrib.put("name1", new Attribute("Value 1a"));
+        name2attrib.put("name3", new Attribute("Value 3"));
+        context.addMissing(name2attrib);
+        attribute = context.getAttribute("name1");
+        assertNotNull("Attribute name1 not found", attribute);
+        assertEquals("Attribute name1 has not been set correctly", "Value 1a",
+                attribute.getValue());
+        attribute = context.getAttribute("name3");
+        assertNotNull("Attribute name3 not found", attribute);
+        assertEquals("Attribute name3 has not been set correctly", "Value 3",
+                attribute.getValue());
+
+        context = new BasicAttributeContext();
+        context.putAttribute("name2", new Attribute("Value 2a"), true);
+        name2attrib = new HashMap<String, Attribute>();
+        name2attrib.put("name1", new Attribute("Value 1a"));
+        name2attrib.put("name3", new Attribute("Value 3"));
+        context.addMissing(name2attrib);
+        attribute = context.getAttribute("name1");
+        assertNotNull("Attribute name1 not found", attribute);
+        assertEquals("Attribute name1 has not been set correctly", "Value 1a",
+                attribute.getValue());
+        attribute = context.getAttribute("name2");
+        assertNotNull("Attribute name2 not found", attribute);
+        assertEquals("Attribute name2 has not been set correctly", "Value 2a",
+                attribute.getValue());
+        attribute = context.getAttribute("name3");
+        assertNotNull("Attribute name3 not found", attribute);
+        assertEquals("Attribute name3 has not been set correctly", "Value 3",
+                attribute.getValue());
+
+        context = new BasicAttributeContext();
+        context.putAttribute("name2", new Attribute("Value 2a"), true);
+        name2attrib = new HashMap<String, Attribute>();
+        name2attrib.put("name2", new Attribute("Value 2b"));
+        name2attrib.put("name3", new Attribute("Value 3"));
+        context.addMissing(name2attrib);
+        attribute = context.getAttribute("name2");
+        assertNotNull("Attribute name2 not found", attribute);
+        assertEquals("Attribute name2 has not been set correctly", "Value 2a",
+                attribute.getValue());
+        attribute = context.getAttribute("name3");
+        assertNotNull("Attribute name3 not found", attribute);
+        assertEquals("Attribute name3 has not been set correctly", "Value 3",
+                attribute.getValue());
+    }
+
+    /**
+     * Tests {@link BasicAttributeContext#getAttribute(String)}.
+     */
+    @Test
+    public void testGetAttribute() {
+        AttributeContext context = new BasicAttributeContext();
+        context.putAttribute("name1", new Attribute("value1"), false);
+        context.putAttribute("name2", new Attribute("value2"), true);
+        context.putAttribute("name3", new Attribute("value3a"), true);
+        context.putAttribute("name3", new Attribute("value3"), false);
+        Attribute attribute = context.getAttribute("name1");
+        assertNotNull("Attribute name1 not found", attribute);
+        assertEquals("Attribute name1 has not been set correctly", "value1",
+                attribute.getValue());
+        attribute = context.getAttribute("name2");
+        assertNotNull("Attribute name2 not found", attribute);
+        assertEquals("Attribute name2 has not been set correctly", "value2",
+                attribute.getValue());
+        attribute = context.getAttribute("name3");
+        assertNotNull("Attribute name3 not found", attribute);
+        assertEquals("Attribute name3 has not been set correctly", "value3",
+                attribute.getValue());
+    }
+
+    /**
+     * Tests {@link BasicAttributeContext#getLocalAttribute(String)}.
+     */
+    @Test
+    public void testGetLocalAttribute() {
+        AttributeContext context = new BasicAttributeContext();
+        context.putAttribute("name1", new Attribute("value1"), false);
+        context.putAttribute("name2", new Attribute("value2"), true);
+        context.putAttribute("name3", new Attribute("value3a"), true);
+        context.putAttribute("name3", new Attribute("value3"), false);
+        Attribute attribute = context.getLocalAttribute("name1");
+        assertNotNull("Attribute name1 not found", attribute);
+        assertEquals("Attribute name1 has not been set correctly", "value1",
+                attribute.getValue());
+        attribute = context.getLocalAttribute("name2");
+        assertNull("Attribute name2 found", attribute);
+        attribute = context.getLocalAttribute("name3");
+        assertNotNull("Attribute name3 not found", attribute);
+        assertEquals("Attribute name3 has not been set correctly", "value3",
+                attribute.getValue());
+    }
+
+    /**
+     * Tests {@link BasicAttributeContext#getCascadedAttribute(String)}.
+     */
+    @Test
+    public void testGetCascadedAttribute() {
+        AttributeContext context = new BasicAttributeContext();
+        context.putAttribute("name1", new Attribute("value1"), false);
+        context.putAttribute("name2", new Attribute("value2"), true);
+        context.putAttribute("name3", new Attribute("value3a"), true);
+        context.putAttribute("name3", new Attribute("value3"), false);
+        Attribute attribute = context.getCascadedAttribute("name1");
+        assertNull("Attribute name1 found", attribute);
+        attribute = context.getCascadedAttribute("name2");
+        assertNotNull("Attribute name2 not found", attribute);
+        assertEquals("Attribute name2 has not been set correctly", "value2",
+                attribute.getValue());
+        attribute = context.getCascadedAttribute("name3");
+        assertNotNull("Attribute name3 not found", attribute);
+        assertEquals("Attribute name3 has not been set correctly", "value3a",
+                attribute.getValue());
+    }
+
+    /**
+     * Tests {@link BasicAttributeContext#getLocalAttributeNames()}.
+     */
+    @Test
+    public void testGetLocalAttributeNames() {
+        AttributeContext context = new BasicAttributeContext();
+        context.putAttribute("name1", new Attribute("value1"), false);
+        context.putAttribute("name2", new Attribute("value2"), true);
+        context.putAttribute("name3", new Attribute("value3a"), true);
+        context.putAttribute("name3", new Attribute("value3"), false);
+        Set<String> names = context.getLocalAttributeNames();
+        assertTrue("Attribute name1 is not present", names.contains("name1"));
+        assertFalse("Attribute name2 is present", names.contains("name2"));
+        assertTrue("Attribute name3 is not present", names.contains("name3"));
+    }
+
+    /**
+     * Tests {@link BasicAttributeContext#getCascadedAttributeNames()}.
+     */
+    @Test
+    public void testGetCascadedAttributeNames() {
+        AttributeContext context = new BasicAttributeContext();
+        context.putAttribute("name1", new Attribute("value1"), false);
+        context.putAttribute("name2", new Attribute("value2"), true);
+        context.putAttribute("name3", new Attribute("value3a"), true);
+        context.putAttribute("name3", new Attribute("value3"), false);
+        Set<String> names = context.getCascadedAttributeNames();
+        assertFalse("Attribute name1 is present", names.contains("name1"));
+        assertTrue("Attribute name2 is not present", names.contains("name2"));
+        assertTrue("Attribute name3 is not present", names.contains("name3"));
+    }
+
+    /**
+     * Tests {@link BasicAttributeContext#putAttribute(String, Attribute)}.
+     */
+    @Test
+    public void testPutAttributeStringAttribute() {
+        AttributeContext context = new BasicAttributeContext();
+        context.putAttribute("name1", new Attribute("value1"));
+        Attribute attribute = context.getLocalAttribute("name1");
+        assertNotNull("Attribute name1 not found", attribute);
+        assertEquals("Attribute name1 has not been set correctly", "value1",
+                attribute.getValue());
+        attribute = context.getCascadedAttribute("name1");
+        assertNull("Attribute name1 found", attribute);
+    }
+
+    /**
+     * Tests
+     * {@link BasicAttributeContext#putAttribute(String, Attribute, boolean)}.
+     */
+    @Test
+    public void testPutAttributeStringAttributeBoolean() {
+        AttributeContext context = new BasicAttributeContext();
+        context.putAttribute("name1", new Attribute("value1"), false);
+        context.putAttribute("name2", new Attribute("value2"), true);
+        Attribute attribute = context.getLocalAttribute("name1");
+        assertNotNull("Attribute name1 not found", attribute);
+        assertEquals("Attribute name1 has not been set correctly", "value1",
+                attribute.getValue());
+        attribute = context.getCascadedAttribute("name1");
+        assertNull("Attribute name1 found", attribute);
+        attribute = context.getCascadedAttribute("name2");
+        assertNotNull("Attribute name2 not found", attribute);
+        assertEquals("Attribute name2 has not been set correctly", "value2",
+                attribute.getValue());
+        attribute = context.getLocalAttribute("name2");
+        assertNull("Attribute name2 found", attribute);
+    }
+
+    /**
+     * Tests {@link BasicAttributeContext#clear()}.
+     */
+    @Test
+    public void testClear() {
+        AttributeContext context = new BasicAttributeContext();
+        context.putAttribute("name1", new Attribute("value1"), false);
+        context.putAttribute("name2", new Attribute("value2"), true);
+        context.clear();
+        Set<String> names = context.getLocalAttributeNames();
+        assertTrue("There are local attributes", names == null
+                || names.isEmpty());
+        names = context.getCascadedAttributeNames();
+        assertTrue("There are cascaded attributes", names == null
+                || names.isEmpty());
+    }
+
+    /**
+     * Tests {@link BasicAttributeContext#equals(Object)}.
+     */
+    @Test
+    public void testEquals() {
+        BasicAttributeContext attributeContext = new BasicAttributeContext();
+        attributeContext.setPreparer("my.preparer");
+        attributeContext.setTemplateAttribute(Attribute.createTemplateAttribute("/my/template.jsp"));
+        attributeContext.putAttribute("attribute1", new Attribute("value1"), true);
+        attributeContext.putAttribute("attribute2", new Attribute("value2"), true);
+        attributeContext.putAttribute("attribute3", new Attribute("value3"), false);
+        BasicAttributeContext toCompare = new BasicAttributeContext(attributeContext);
+        assertTrue(toCompare.equals(attributeContext));
+        toCompare = new BasicAttributeContext(attributeContext);
+        toCompare.putAttribute("attribute4", new Attribute("value4"), true);
+        assertFalse(toCompare.equals(attributeContext));
+        toCompare = new BasicAttributeContext(attributeContext);
+        toCompare.putAttribute("attribute4", new Attribute("value4"), false);
+        assertFalse(toCompare.equals(attributeContext));
+        toCompare = new BasicAttributeContext(attributeContext);
+        toCompare.setPreparer("another.preparer");
+        assertFalse(toCompare.equals(attributeContext));
+        toCompare = new BasicAttributeContext(attributeContext);
+        toCompare.setTemplateAttribute(Attribute.createTemplateAttribute("/another/template.jsp"));
+        assertFalse(toCompare.equals(attributeContext));
+    }
+
+    /**
+     * Tests {@link BasicAttributeContext#hashCode()}.
+     */
+    @Test
+    public void testHashCode() {
+        BasicAttributeContext attributeContext = new BasicAttributeContext();
+        attributeContext.setPreparer("my.preparer");
+        Attribute templateAttribute = Attribute.createTemplateAttribute("/my/template.jsp");
+        attributeContext.setTemplateAttribute(templateAttribute);
+        Attribute attribute1 = new Attribute("value1");
+        Attribute attribute2 = new Attribute("value2");
+        Attribute attribute3 = new Attribute("value3");
+        attributeContext.putAttribute("attribute1", attribute1, true);
+        attributeContext.putAttribute("attribute2", attribute2, true);
+        attributeContext.putAttribute("attribute3", attribute3, false);
+        Map<String, Attribute> cascadedAttributes = new HashMap<String, Attribute>();
+        cascadedAttributes.put("attribute1", attribute1);
+        cascadedAttributes.put("attribute2", attribute2);
+        Map<String, Attribute> attributes = new HashMap<String, Attribute>();
+        attributes.put("attribute3", attribute3);
+        assertEquals(templateAttribute.hashCode() + "my.preparer".hashCode()
+                + attributes.hashCode() + cascadedAttributes.hashCode(),
+                attributeContext.hashCode());
+    }
+
+    /**
+     * Tests {@link BasicAttributeContext} for the TILES-429 bug.
+     */
+    @Test
+    public void testTiles429() {
+        AttributeContext toCopy = new BasicAttributeContext();
+        toCopy.putAttribute("name1", new Attribute("value1"), false);
+        toCopy.putAttribute("name2", new Attribute("value2"), true);
+        List<Attribute> listOfObjects = new ArrayList<Attribute>();
+        Attribute attribute1 = new Attribute(1);
+        listOfObjects.add(attribute1);
+        ListAttribute listAttribute = new ListAttribute(listOfObjects);
+        listAttribute.setInherit(true);
+        toCopy.putAttribute("name3", listAttribute);
+        Attribute templateAttribute = Attribute
+                .createTemplateAttribute("/template.jsp");
+        Set<String> roles = new HashSet<String>();
+        roles.add("role1");
+        roles.add("role2");
+        templateAttribute.setRoles(roles);
+        toCopy.setTemplateAttribute(templateAttribute);
+        toCopy.setPreparer("my.preparer.Preparer");
+        AttributeContext context = new BasicAttributeContext(toCopy);
+        Attribute attribute = context.getAttribute("name1");
+        attribute.setValue("newValue1");
+        attribute = context.getAttribute("name1");
+        assertEquals("newValue1", attribute.getValue());
+        attribute = toCopy.getAttribute("name1");
+        assertEquals("value1", attribute.getValue());
+        attribute = context.getAttribute("name3");
+        assertTrue(attribute instanceof ListAttribute);
+        assertTrue(((ListAttribute) attribute).isInherit());
+    }
+}
diff --git a/Java-base/tiles/src/tiles-api/src/test/java/org/apache/tiles/CompareUtilTest.java b/Java-base/tiles/src/tiles-api/src/test/java/org/apache/tiles/CompareUtilTest.java
new file mode 100644
index 000000000..d87201ddc
--- /dev/null
+++ b/Java-base/tiles/src/tiles-api/src/test/java/org/apache/tiles/CompareUtilTest.java
@@ -0,0 +1,60 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+/**
+ * Tests {@link CompareUtil}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class CompareUtilTest {
+
+    /**
+     * A test value.
+     */
+    private static final Integer TEST_VALUE = 10;
+
+    /**
+     * Test method for {@link org.apache.tiles.CompareUtil#nullSafeEquals(java.lang.Object, java.lang.Object)}.
+     */
+    @Test
+    public void testNullSafeEquals() {
+        assertTrue(CompareUtil.nullSafeEquals(1, 1));
+        assertFalse(CompareUtil.nullSafeEquals(1, 2));
+        assertFalse(CompareUtil.nullSafeEquals(1, null));
+        assertFalse(CompareUtil.nullSafeEquals(null, 1));
+        assertTrue(CompareUtil.nullSafeEquals(null, null));
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.CompareUtil#nullSafeHashCode(java.lang.Object)}.
+     */
+    @Test
+    public void testNullSafeHashCode() {
+        assertEquals(TEST_VALUE.hashCode(), CompareUtil.nullSafeHashCode(TEST_VALUE));
+        assertEquals(0, CompareUtil.nullSafeHashCode(null));
+    }
+}
diff --git a/Java-base/tiles/src/tiles-api/src/test/java/org/apache/tiles/ExpressionTest.java b/Java-base/tiles/src/tiles-api/src/test/java/org/apache/tiles/ExpressionTest.java
new file mode 100644
index 000000000..dc23f6925
--- /dev/null
+++ b/Java-base/tiles/src/tiles-api/src/test/java/org/apache/tiles/ExpressionTest.java
@@ -0,0 +1,134 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+/**
+ * Tests {@link Expression}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ExpressionTest {
+
+    /**
+     * Test method for {@link org.apache.tiles.Expression#hashCode()}.
+     */
+    @Test
+    public void testHashCode() {
+        Expression expression = new Expression("hello", "there");
+        assertEquals("hello".hashCode() + "there".hashCode(), expression.hashCode());
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.Expression#Expression(java.lang.String, java.lang.String)}.
+     */
+    @Test
+    public void testExpressionStringString() {
+        Expression expression = new Expression("hello", "there");
+        assertEquals("hello", expression.getExpression());
+        assertEquals("there", expression.getLanguage());
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.Expression#Expression(java.lang.String)}.
+     */
+    @Test
+    public void testExpressionString() {
+        Expression expression = new Expression("hello");
+        assertEquals("hello", expression.getExpression());
+        assertNull(expression.getLanguage());
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.Expression#Expression(org.apache.tiles.Expression)}.
+     */
+    @Test
+    public void testExpressionExpression() {
+        Expression expression = new Expression("hello", "there");
+        Expression expression2 = new Expression(expression);
+        assertEquals("hello", expression2.getExpression());
+        assertEquals("there", expression2.getLanguage());
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.Expression#createExpressionFromDescribedExpression(java.lang.String)}.
+     */
+    @Test
+    public void testCreateExpressionFromDescribedExpression() {
+        Expression expression = Expression.createExpressionFromDescribedExpression("hello");
+        assertEquals("hello", expression.getExpression());
+        assertNull(expression.getLanguage());
+        expression = Expression.createExpressionFromDescribedExpression("there:hello");
+        assertEquals("hello", expression.getExpression());
+        assertEquals("there", expression.getLanguage());
+        expression = Expression.createExpressionFromDescribedExpression("there_:hello");
+        assertEquals("there_:hello", expression.getExpression());
+        assertNull(expression.getLanguage());
+        assertNull(Expression.createExpressionFromDescribedExpression(null));
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.Expression#createExpression(java.lang.String, java.lang.String)}.
+     */
+    @Test
+    public void testCreateExpression() {
+        Expression expression = Expression.createExpression("hello", "there");
+        assertEquals("hello", expression.getExpression());
+        assertEquals("there", expression.getLanguage());
+        expression = Expression.createExpression("hello", null);
+        assertEquals("hello", expression.getExpression());
+        assertNull(expression.getLanguage());
+        expression = Expression.createExpression(null, "there");
+        assertNull(expression);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.Expression#equals(java.lang.Object)}.
+     */
+    @Test
+    public void testEqualsObject() {
+        Expression expression = new Expression("hello", "there");
+        Expression expression2 = new Expression("hello", "there");
+        assertEquals(expression, expression2);
+        expression2 = new Expression("hello", "there2");
+        assertFalse(expression.equals(expression2));
+        expression2 = new Expression("hello");
+        assertFalse(expression.equals(expression2));
+        expression = new Expression("hello");
+        assertEquals(expression, expression2);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.Expression#toString()}.
+     */
+    @Test
+    public void testToString() {
+        Expression expression = new Expression("hello", "there");
+        assertEquals("there:hello", expression.toString());
+        expression = new Expression("hello");
+        assertEquals("DEFAULT:hello", expression.toString());
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-api/src/test/java/org/apache/tiles/ListAttributeTest.java b/Java-base/tiles/src/tiles-api/src/test/java/org/apache/tiles/ListAttributeTest.java
new file mode 100644
index 000000000..314e63954
--- /dev/null
+++ b/Java-base/tiles/src/tiles-api/src/test/java/org/apache/tiles/ListAttributeTest.java
@@ -0,0 +1,187 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles;
+
+import static org.junit.Assert.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+
+/**
+ * Tests {@link ListAttribute}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ListAttributeTest {
+
+    /**
+     * The list size.
+     */
+    private static final int LIST_SIZE = 3;
+
+    /**
+     * Test method for {@link org.apache.tiles.ListAttribute#hashCode()}.
+     */
+    @Test
+    public void testHashCode() {
+        ListAttribute attribute = new ListAttribute();
+        List<Attribute> list = new ArrayList<Attribute>();
+        list.add(new Attribute("value1"));
+        list.add(new Attribute("value2"));
+        attribute.setValue(list);
+        attribute.setInherit(true);
+        assertEquals(list.hashCode() + Boolean.TRUE.hashCode(), attribute.hashCode());
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.ListAttribute#equals(java.lang.Object)}.
+     */
+    @Test
+    public void testEqualsObject() {
+        ListAttribute attribute = new ListAttribute();
+        List<Attribute> list = new ArrayList<Attribute>();
+        list.add(new Attribute("value1"));
+        list.add(new Attribute("value2"));
+        attribute.setValue(list);
+        attribute.setInherit(true);
+        ListAttribute toCheck = new ListAttribute(attribute);
+        assertTrue(attribute.equals(toCheck));
+        toCheck = new ListAttribute(attribute);
+        toCheck.setInherit(false);
+        assertFalse(attribute.equals(toCheck));
+        toCheck = new ListAttribute(attribute);
+        toCheck.add(new Attribute("value3"));
+        assertFalse(attribute.equals(toCheck));
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.ListAttribute#ListAttribute(java.util.List)}.
+     */
+    @Test
+    public void testListAttributeListOfAttribute() {
+        List<Attribute> attributes = new ArrayList<Attribute>();
+        attributes.add(new Attribute("value1"));
+        attributes.add(new Attribute("value2"));
+        ListAttribute attribute = new ListAttribute(attributes);
+        assertEquals(attributes, attribute.getValue());
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.ListAttribute#ListAttribute(org.apache.tiles.ListAttribute)}.
+     */
+    @Test
+    public void testListAttributeListAttribute() {
+        ListAttribute attribute = new ListAttribute();
+        List<Attribute> list = new ArrayList<Attribute>();
+        list.add(new Attribute("value1"));
+        list.add(new Attribute("value2"));
+        list.add(null);
+        attribute.setValue(list);
+        attribute.setInherit(true);
+        ListAttribute toCheck = new ListAttribute(attribute);
+        assertEquals(attribute, toCheck);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.ListAttribute#setValue(java.util.List)}.
+     */
+    @Test
+    public void testSetValue() {
+        ListAttribute attribute = new ListAttribute();
+        List<Attribute> list = new ArrayList<Attribute>();
+        list.add(new Attribute("value1"));
+        list.add(new Attribute("value2"));
+        attribute.setValue(list);
+        assertEquals(list, attribute.getValue());
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.ListAttribute#add(org.apache.tiles.Attribute)}.
+     */
+    @Test
+    public void testAdd() {
+        List<Attribute> list = new ArrayList<Attribute>();
+        Attribute attribute1 = new Attribute("value1");
+        list.add(attribute1);
+        Attribute attribute2 = new Attribute("value2");
+        list.add(attribute2);
+        ListAttribute attribute = new ListAttribute(list);
+        Attribute attribute3 = new Attribute("value3");
+        attribute.add(attribute3);
+        list = attribute.getValue();
+        assertEquals(LIST_SIZE, list.size());
+        assertEquals(attribute1, list.get(0));
+        assertEquals(attribute2, list.get(1));
+        assertEquals(attribute3, list.get(2));
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.ListAttribute#setInherit(boolean)}.
+     */
+    @Test
+    public void testSetInherit() {
+        ListAttribute attribute = new ListAttribute();
+        attribute.setInherit(true);
+        assertTrue(attribute.isInherit());
+        attribute.setInherit(false);
+        assertFalse(attribute.isInherit());
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.ListAttribute#inherit(org.apache.tiles.ListAttribute)}.
+     */
+    @Test
+    public void testInherit() {
+        List<Attribute> list = new ArrayList<Attribute>();
+        Attribute attribute1 = new Attribute("value1");
+        list.add(attribute1);
+        Attribute attribute2 = new Attribute("value2");
+        list.add(attribute2);
+        ListAttribute parent = new ListAttribute(list);
+        Attribute attribute3 = new Attribute("value3");
+        ListAttribute child = new ListAttribute();
+        child.add(attribute3);
+        child.inherit(parent);
+        list = child.getValue();
+        assertEquals(LIST_SIZE, list.size());
+        assertEquals(attribute1, list.get(0));
+        assertEquals(attribute2, list.get(1));
+        assertEquals(attribute3, list.get(2));
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.ListAttribute#clone()}.
+     */
+    @Test
+    public void testClone() {
+        ListAttribute attribute = new ListAttribute();
+        List<Attribute> list = new ArrayList<Attribute>();
+        list.add(new Attribute("value1"));
+        list.add(new Attribute("value2"));
+        attribute.setValue(list);
+        attribute.setInherit(true);
+        ListAttribute toCheck = attribute.clone();
+        assertEquals(attribute, toCheck);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-api/src/test/java/org/apache/tiles/NoSuchContainerExceptionTest.java b/Java-base/tiles/src/tiles-api/src/test/java/org/apache/tiles/NoSuchContainerExceptionTest.java
new file mode 100644
index 000000000..c700a1b15
--- /dev/null
+++ b/Java-base/tiles/src/tiles-api/src/test/java/org/apache/tiles/NoSuchContainerExceptionTest.java
@@ -0,0 +1,77 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+/**
+ * Tests {@link NoSuchContainerException}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class NoSuchContainerExceptionTest {
+
+    /**
+     * Test method for {@link org.apache.tiles.NoSuchContainerException#NoSuchContainerException()}.
+     */
+    @Test
+    public void testNoSuchContainerException() {
+        NoSuchContainerException exception = new NoSuchContainerException();
+        assertNull(exception.getMessage());
+        assertNull(exception.getCause());
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.NoSuchContainerException#NoSuchContainerException(java.lang.String)}.
+     */
+    @Test
+    public void testNoSuchContainerExceptionString() {
+        NoSuchContainerException exception = new NoSuchContainerException("my message");
+        assertEquals("my message", exception.getMessage());
+        assertNull(exception.getCause());
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.NoSuchContainerException#NoSuchContainerException(java.lang.Throwable)}.
+     */
+    @Test
+    public void testNoSuchContainerExceptionThrowable() {
+        Throwable cause = new Throwable();
+        NoSuchContainerException exception = new NoSuchContainerException(cause);
+        assertEquals(cause.toString(), exception.getMessage());
+        assertEquals(cause, exception.getCause());
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.NoSuchContainerException#NoSuchContainerException(java.lang.String, java.lang.Throwable)}.
+     */
+    @Test
+    public void testNoSuchContainerExceptionStringThrowable() {
+        Throwable cause = new Throwable();
+        NoSuchContainerException exception = new NoSuchContainerException("my message", cause);
+        assertEquals("my message", exception.getMessage());
+        assertEquals(cause, exception.getCause());
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-api/src/test/java/org/apache/tiles/TestDefinition.java b/Java-base/tiles/src/tiles-api/src/test/java/org/apache/tiles/TestDefinition.java
new file mode 100644
index 000000000..0f28554ba
--- /dev/null
+++ b/Java-base/tiles/src/tiles-api/src/test/java/org/apache/tiles/TestDefinition.java
@@ -0,0 +1,252 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles;
+
+import static org.junit.Assert.*;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Test;
+
+/**
+ * Tests the Definition class.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TestDefinition {
+
+    /**
+     * Tests {@link Definition#Definition(Definition)}.
+     */
+    @Test
+    public void testDefinitionCopy() {
+        Definition definition = new Definition();
+        definition.setName("myDefinition");
+        definition.setExtends("myExtends");
+        Attribute attribute1 = new Attribute("value1");
+        definition.putAttribute("name1", attribute1);
+        Attribute attribute2 = new Attribute("value2");
+        definition.putAttribute("name2", attribute2);
+        Definition toCheck = new Definition(definition);
+        assertEquals("myDefinition", toCheck.getName());
+        assertEquals("myExtends", toCheck.getExtends());
+        assertEquals(attribute1, toCheck.getAttribute("name1"));
+        assertEquals(attribute2, toCheck.getAttribute("name2"));
+    }
+
+    /**
+     * Tests {@link Definition#Definition(Definition)}.
+     */
+    @Test
+    public void testDefinitionComplete() {
+        Map<String, Attribute> attributeMap = new HashMap<String, Attribute>();
+        Attribute attribute1 = new Attribute("value1");
+        Attribute attribute2 = new Attribute("value2");
+        attributeMap.put("name1", attribute1);
+        attributeMap.put("name2", attribute2);
+        Attribute templateAttribute = Attribute.createTemplateAttribute("/my/template.jsp");
+        Definition definition = new Definition("myDefinition",
+                templateAttribute, attributeMap);
+        assertEquals("myDefinition", definition.getName());
+        assertEquals(templateAttribute, definition.getTemplateAttribute());
+        assertEquals(attribute1, definition.getAttribute("name1"));
+        assertEquals(attribute2, definition.getAttribute("name2"));
+    }
+
+    /**
+     * Verifies the put Attribute functionality.
+     *
+     * Attributes are added or replaced in the definition.
+     */
+    @Test
+    public void testPutAttribute() {
+        Definition def = new Definition();
+        def.setName("test1");
+        def.setTemplateAttribute(Attribute
+                .createTemplateAttribute("/page1.jsp"));
+        Attribute attr1 = new Attribute("test.definition.name",
+                (Expression) null, null, "definition");
+        def.putAttribute("attr1",  attr1);
+
+        attr1 = def.getAttribute("attr1");
+        assertNotNull("Null attribute.", attr1);
+        assertTrue("Wrong attribute type", "definition".equals(attr1
+                .getRenderer()));
+    }
+
+    /**
+     * Tests the {@link Definition#inherit(BasicAttributeContext)} method.
+     */
+    @Test
+    public void testInherit() {
+        Definition toCopy = new Definition();
+        toCopy.putAttribute("name1", new Attribute("value1"), true);
+        toCopy.putAttribute("name2", new Attribute("value2"), true);
+        toCopy.putAttribute("name3", new Attribute("value3"), false);
+        toCopy.putAttribute("name4", new Attribute("value4"), false);
+        Definition context = new Definition();
+        toCopy.putAttribute("name1", new Attribute("newValue1"), true);
+        toCopy.putAttribute("name3", new Attribute("newValue3"), false);
+        context.inherit(toCopy);
+        Attribute attribute = context.getCascadedAttribute("name1");
+        assertNotNull("Attribute name1 not found", attribute);
+        assertEquals("Attribute name1 has not been set correctly", "newValue1",
+                attribute.getValue());
+        attribute = context.getCascadedAttribute("name2");
+        assertNotNull("Attribute name2 not found", attribute);
+        assertEquals("Attribute name2 has not been set correctly", "value2",
+                attribute.getValue());
+        attribute = context.getLocalAttribute("name3");
+        assertNotNull("Attribute name3 not found", attribute);
+        assertEquals("Attribute name3 has not been set correctly", "newValue3",
+                attribute.getValue());
+        attribute = context.getLocalAttribute("name4");
+        assertNotNull("Attribute name4 not found", attribute);
+        assertEquals("Attribute name4 has not been set correctly", "value4",
+                attribute.getValue());
+
+        toCopy = new Definition();
+        toCopy.setPreparer("ExtendedPreparer");
+        Attribute templateAttribute = new Attribute("extendedTemplate.jsp",
+                Expression.createExpression("expression", "language"),
+                "extendedRole", "template");
+        toCopy.setTemplateAttribute(templateAttribute);
+        context = new Definition();
+        context.inherit(toCopy);
+        assertEquals("Preparer not inherited", "ExtendedPreparer", context
+                .getPreparer());
+        assertNotNull("Roles not inherited", context.getTemplateAttribute()
+                .getRoles());
+        assertEquals("Roles not inherited", context.getTemplateAttribute()
+                .getRoles().size(), 1);
+        assertTrue("Roles not inherited", context.getTemplateAttribute()
+                .getRoles().contains(
+                "extendedRole"));
+        assertEquals("Template not inherited", "extendedTemplate.jsp", context
+                .getTemplateAttribute().getValue());
+        assertEquals("Template expression not inherited", "expression", context
+                .getTemplateAttribute().getExpressionObject().getExpression());
+        assertEquals("Template expression language not inherited", "language",
+                context.getTemplateAttribute().getExpressionObject()
+                        .getLanguage());
+        context = new Definition();
+        context.setPreparer("LocalPreparer");
+        templateAttribute = new Attribute("localTemplate.jsp", Expression
+                .createExpression("localExpression", "localLanguage"),
+                "localRole", "template");
+        context.setTemplateAttribute(templateAttribute);
+        assertEquals("Preparer inherited", "LocalPreparer", context
+                .getPreparer());
+        assertNotNull("Roles not correct", context.getTemplateAttribute()
+                .getRoles());
+        assertEquals("Roles not correct", context.getTemplateAttribute()
+                .getRoles().size(), 1);
+        assertTrue("Roles inherited", context.getTemplateAttribute().getRoles()
+                .contains("localRole"));
+        assertEquals("Template inherited", "localTemplate.jsp", context
+                .getTemplateAttribute().getValue());
+        assertEquals("Template expression inherited", "localExpression",
+                context.getTemplateAttribute().getExpressionObject()
+                        .getExpression());
+        assertEquals("Template expression language not inherited",
+                "localLanguage", context.getTemplateAttribute()
+                        .getExpressionObject().getLanguage());
+    }
+
+    /**
+     * Tests {@link Definition#toString()}.
+     */
+    @Test
+    public void testToString() {
+        Definition definition = new Definition();
+        definition.setName("myDefinitionName");
+        assertEquals(
+                "{name=myDefinitionName, template=<null>, role=<null>, preparerInstance=null, attributes=null}",
+                definition.toString());
+        definition.setTemplateAttribute(Attribute.createTemplateAttribute("myTemplate"));
+        assertEquals(
+                "{name=myDefinitionName, template=myTemplate, role=null, preparerInstance=null, attributes=null}",
+                definition.toString());
+        definition.putAttribute("myAttributeName", new Attribute("myAttributeValue"));
+        assertEquals(
+                "{name=myDefinitionName, template=myTemplate, role=null, preparerInstance=null, "
+                        + "attributes={myAttributeName=myAttributeValue}}",
+                definition.toString());
+    }
+
+    /**
+     * Tests {@link Definition#equals(Object)}.
+     */
+    @Test
+    public void testEquals() {
+        Definition definition = new Definition();
+        definition.setName("myDefinition");
+        definition.setExtends("myExtends");
+        Attribute attribute1 = new Attribute("value1");
+        definition.putAttribute("name1", attribute1);
+        Attribute attribute2 = new Attribute("value2");
+        definition.putAttribute("name2", attribute2);
+        Definition toCheck = new Definition(definition);
+        assertTrue(definition.equals(toCheck));
+        toCheck = new Definition(definition);
+        toCheck.setName("anotherDefinition");
+        assertFalse(definition.equals(toCheck));
+        toCheck = new Definition(definition);
+        toCheck.setExtends("anotherExtends");
+        assertFalse(definition.equals(toCheck));
+        toCheck = new Definition(definition);
+        toCheck.putAttribute("name1", new Attribute("anotherAttribute"));
+        assertFalse(definition.equals(toCheck));
+    }
+
+    /**
+     * Tests {@link Definition#hashCode()}.
+     */
+    @Test
+    public void testHashCode() {
+        Definition definition = new Definition();
+        definition.setName("myDefinition");
+        definition.setExtends("myExtends");
+        Attribute attribute1 = new Attribute("value1");
+        definition.putAttribute("name1", attribute1);
+        Attribute attribute2 = new Attribute("value2");
+        definition.putAttribute("name2", attribute2);
+        BasicAttributeContext attributeContext = new BasicAttributeContext();
+        attributeContext.putAttribute("name1", attribute1);
+        attributeContext.putAttribute("name2", attribute2);
+        assertEquals("myDefinition".hashCode() + "myExtends".hashCode()
+                + attributeContext.hashCode(), definition.hashCode());
+    }
+
+    /**
+     * Tests {@link Definition#isExtending()}.
+     */
+    @Test
+    public void testIsExtending() {
+        Definition definition = new Definition();
+        definition.setName("myDefinition");
+        assertFalse(definition.isExtending());
+        definition.setExtends("myExtends");
+        assertTrue(definition.isExtending());
+    }
+}
diff --git a/Java-base/tiles/src/tiles-api/src/test/java/org/apache/tiles/TilesContainerWrapperTest.java b/Java-base/tiles/src/tiles-api/src/test/java/org/apache/tiles/TilesContainerWrapperTest.java
new file mode 100644
index 000000000..46f7ada03
--- /dev/null
+++ b/Java-base/tiles/src/tiles-api/src/test/java/org/apache/tiles/TilesContainerWrapperTest.java
@@ -0,0 +1,252 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles;
+
+import static org.easymock.classextension.EasyMock.*;
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.Request;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests {@link TilesContainerWrapper}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TilesContainerWrapperTest {
+
+    /**
+     * The container.
+     */
+    private TilesContainer container;
+
+    /**
+     * The wrapper to test.
+     */
+    private TilesContainerWrapper wrapper;
+
+    /**
+     * Sets up the test.
+     */
+    @Before
+    public void setUp() {
+        container = createMock(TilesContainer.class);
+        wrapper = new TilesContainerWrapper(container);
+    }
+
+    /**
+     * Tests {@link TilesContainerWrapper#TilesContainerWrapper(TilesContainer)}.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testTilesContainerWrapperNPE() {
+        new TilesContainerWrapper(null);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.TilesContainerWrapper#getWrappedContainer()}.
+     */
+    @Test
+    public void testGetWrappedContainer() {
+        replay(container);
+        assertSame(container, wrapper.getWrappedContainer());
+        verify(container);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.TilesContainerWrapper#endContext(org.apache.tiles.request.Request)}.
+     */
+    @Test
+    public void testEndContext() {
+        Request request = createMock(Request.class);
+
+        container.endContext(request);
+
+        replay(container, request);
+        wrapper.endContext(request);
+        verify(container, request);
+    }
+
+    /**
+     * Test method for {@link TilesContainerWrapper#evaluate(Attribute, Request)}.
+     */
+    @Test
+    public void testEvaluate() {
+        Request request = createMock(Request.class);
+        Attribute attribute = createMock(Attribute.class);
+
+        expect(container.evaluate(attribute, request)).andReturn(new Integer(1));
+
+        replay(container, request, attribute);
+        assertEquals(new Integer(1), wrapper.evaluate(attribute, request));
+        verify(container, request, attribute);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.TilesContainerWrapper#getApplicationContext()}.
+     */
+    @Test
+    public void testGetApplicationContext() {
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+
+        expect(container.getApplicationContext()).andReturn(applicationContext);
+
+        replay(container, applicationContext);
+        assertSame(applicationContext, wrapper.getApplicationContext());
+        verify(container, applicationContext);
+    }
+
+    /**
+     * Test method for {@link TilesContainerWrapper#getAttributeContext(Request)}.
+     */
+    @Test
+    public void testGetAttributeContext() {
+        Request request = createMock(Request.class);
+        AttributeContext attribute = createMock(AttributeContext.class);
+
+        expect(container.getAttributeContext(request)).andReturn(attribute);
+
+        replay(container, request, attribute);
+        assertSame(attribute, wrapper.getAttributeContext(request));
+        verify(container, request, attribute);
+    }
+
+    /**
+     * Test method for {@link TilesContainerWrapper#getDefinition(String, Request)}.
+     */
+    @Test
+    public void testGetDefinition() {
+        Request request = createMock(Request.class);
+        Definition definition = createMock(Definition.class);
+
+        expect(container.getDefinition("definition", request)).andReturn(definition);
+
+        replay(container, request, definition);
+        assertSame(definition, wrapper.getDefinition("definition", request));
+        verify(container, request, definition);
+    }
+
+    /**
+     * Test method for {@link TilesContainerWrapper#isValidDefinition(String, Request)}.
+     */
+    @Test
+    public void testIsValidDefinition() {
+        Request request = createMock(Request.class);
+
+        expect(container.isValidDefinition("definition", request)).andReturn(true);
+
+        replay(container, request);
+        assertTrue(wrapper.isValidDefinition("definition", request));
+        verify(container, request);
+    }
+
+    /**
+     * Test method for {@link TilesContainerWrapper#prepare(String, Request)}.
+     */
+    @Test
+    public void testPrepare() {
+        Request request = createMock(Request.class);
+
+        container.prepare("preparer", request);
+
+        replay(container, request);
+        wrapper.prepare("preparer", request);
+        verify(container, request);
+    }
+
+    /**
+     * Test method for {@link TilesContainerWrapper#render(String, Request)}.
+     */
+    @Test
+    public void testRenderStringRequest() {
+        Request request = createMock(Request.class);
+
+        container.render("definition", request);
+
+        replay(container, request);
+        wrapper.render("definition", request);
+        verify(container, request);
+    }
+
+    /**
+     * Test method for {@link TilesContainerWrapper#render(Definition, Request)}.
+     */
+    @Test
+    public void testRenderDefinitionRequest() {
+        Request request = createMock(Request.class);
+        Definition definition = createMock(Definition.class);
+
+        container.render(definition, request);
+
+        replay(container, request, definition);
+        wrapper.render(definition, request);
+        verify(container, request, definition);
+    }
+
+    /**
+     * Test method for {@link TilesContainerWrapper#render(Attribute, Request)}.
+     * @throws IOException If something goes wrong.
+     */
+    @Test
+    public void testRenderAttributeRequest() throws IOException {
+        Request request = createMock(Request.class);
+        Attribute attribute = createMock(Attribute.class);
+
+        container.render(attribute, request);
+
+        replay(container, request, attribute);
+        wrapper.render(attribute, request);
+        verify(container, request, attribute);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.TilesContainerWrapper#renderContext(org.apache.tiles.request.Request)}.
+     */
+    @Test
+    public void testRenderContext() {
+        Request request = createMock(Request.class);
+
+        container.renderContext(request);
+
+        replay(container, request);
+        wrapper.renderContext(request);
+        verify(container, request);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.TilesContainerWrapper#startContext(org.apache.tiles.request.Request)}.
+     */
+    @Test
+    public void testStartContext() {
+        Request request = createMock(Request.class);
+        AttributeContext attribute = createMock(AttributeContext.class);
+
+        expect(container.startContext(request)).andReturn(attribute);
+
+        replay(container, request, attribute);
+        assertSame(attribute, wrapper.startContext(request));
+        verify(container, request, attribute);
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-api/src/test/java/org/apache/tiles/TilesExceptionTest.java b/Java-base/tiles/src/tiles-api/src/test/java/org/apache/tiles/TilesExceptionTest.java
new file mode 100644
index 000000000..95ffb22e4
--- /dev/null
+++ b/Java-base/tiles/src/tiles-api/src/test/java/org/apache/tiles/TilesExceptionTest.java
@@ -0,0 +1,77 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+/**
+ * Tests {@link TilesException}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TilesExceptionTest {
+
+    /**
+     * Test method for {@link org.apache.tiles.TilesException#TilesException()}.
+     */
+    @Test
+    public void testTilesException() {
+        TilesException exception = new TilesException();
+        assertNull(exception.getMessage());
+        assertNull(exception.getCause());
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.TilesException#TilesException(java.lang.String)}.
+     */
+    @Test
+    public void testTilesExceptionString() {
+        TilesException exception = new TilesException("my message");
+        assertEquals("my message", exception.getMessage());
+        assertNull(exception.getCause());
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.TilesException#TilesException(java.lang.Throwable)}.
+     */
+    @Test
+    public void testTilesExceptionThrowable() {
+        Throwable cause = new Throwable();
+        TilesException exception = new TilesException(cause);
+        assertEquals(cause.toString(), exception.getMessage());
+        assertEquals(cause, exception.getCause());
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.TilesException#TilesException(java.lang.String, java.lang.Throwable)}.
+     */
+    @Test
+    public void testTilesExceptionStringThrowable() {
+        Throwable cause = new Throwable();
+        TilesException exception = new TilesException("my message", cause);
+        assertEquals("my message", exception.getMessage());
+        assertEquals(cause, exception.getCause());
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-api/src/test/java/org/apache/tiles/access/TilesAccessTest.java b/Java-base/tiles/src/tiles-api/src/test/java/org/apache/tiles/access/TilesAccessTest.java
new file mode 100644
index 000000000..6f076335b
--- /dev/null
+++ b/Java-base/tiles/src/tiles-api/src/test/java/org/apache/tiles/access/TilesAccessTest.java
@@ -0,0 +1,241 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.access;
+
+import static org.junit.Assert.*;
+import static org.easymock.EasyMock.*;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.Test;
+import org.apache.tiles.NoSuchContainerException;
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.Request;
+
+/**
+ * Tests {@link TilesAccess}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TilesAccessTest {
+
+    /**
+     * Tests {@link TilesAccess#setContainer(ApplicationContext, TilesContainer)}.
+     */
+    @Test
+    public void testSetContainer() {
+        ApplicationContext context = createMock(ApplicationContext.class);
+        TilesContainer container = createMock(TilesContainer.class);
+        Map<String, Object> attribs = new HashMap<String, Object>();
+        expect(context.getApplicationScope()).andReturn(attribs);
+        replay(context, container);
+        TilesAccess.setContainer(context, container);
+        assertEquals(attribs.size(), 1);
+        assertEquals(attribs.get(TilesAccess.CONTAINER_ATTRIBUTE), container);
+        verify(context, container);
+    }
+
+    /**
+     * Tests {@link TilesAccess#setContainer(ApplicationContext, TilesContainer, String)}.
+     */
+    @Test
+    public void testSetContainerWithKey() {
+        ApplicationContext context = createMock(ApplicationContext.class);
+        TilesContainer container = createMock(TilesContainer.class);
+        Map<String, Object> attribs = new HashMap<String, Object>();
+        expect(context.getApplicationScope()).andReturn(attribs).anyTimes();
+        replay(context, container);
+        TilesAccess.setContainer(context, container, "myKey");
+        assertEquals(1, attribs.size());
+        assertEquals(container, attribs.get("myKey"));
+
+        TilesAccess.setContainer(context, null, "myKey");
+        assertEquals(0, attribs.size());
+
+        TilesAccess.setContainer(context, container, null);
+        assertEquals(1, attribs.size());
+        assertEquals(container, attribs.get(TilesAccess.CONTAINER_ATTRIBUTE));
+        verify(context, container);
+    }
+
+    /**
+     * Tests {@link TilesAccess#getContainer(ApplicationContext)}.
+     */
+    @Test
+    public void testGetContainer() {
+        ApplicationContext context = createMock(ApplicationContext.class);
+        TilesContainer container = createMock(TilesContainer.class);
+        Map<String, Object> attribs = new HashMap<String, Object>();
+        expect(context.getApplicationScope()).andReturn(attribs).anyTimes();
+
+        replay(context, container);
+        attribs.put(TilesAccess.CONTAINER_ATTRIBUTE, container);
+        assertEquals(container, TilesAccess.getContainer(context));
+        verify(context, container);
+    }
+
+    /**
+     * Tests {@link TilesAccess#getContainer(TilesApplicationContext, String))}.
+     */
+    @Test
+    public void testGetContainerWithKey() {
+        ApplicationContext context = createMock(ApplicationContext.class);
+        TilesContainer container = createMock(TilesContainer.class);
+        Map<String, Object> attribs = new HashMap<String, Object>();
+        expect(context.getApplicationScope()).andReturn(attribs).anyTimes();
+
+        replay(context, container);
+        attribs.put(TilesAccess.CONTAINER_ATTRIBUTE, container);
+        attribs.put("myKey", container);
+        assertEquals(container, TilesAccess.getContainer(context, null));
+        assertEquals(container, TilesAccess.getContainer(context, "myKey"));
+        verify(context, container);
+    }
+
+    /**
+     * Tests
+     * {@link ServletUtil#setCurrentContainer(ServletRequest, String)}.
+     */
+    @Test
+    public void testSetCurrentContainer() {
+        Request request = createMock(Request.class);
+        ApplicationContext context = createMock(ApplicationContext.class);
+        TilesContainer container = createMock(TilesContainer.class);
+        Map<String, Object> attribs = new HashMap<String, Object>();
+        attribs.put("myKey", container);
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+
+        expect(context.getApplicationScope()).andReturn(attribs).anyTimes();
+        expect(request.getContext("request")).andReturn(requestScope);
+        expect(request.getApplicationContext()).andReturn(context);
+        replay(request, context, container);
+        TilesAccess.setCurrentContainer(request, "myKey");
+        assertEquals(container, requestScope.get(TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME));
+        verify(request, context, container);
+    }
+
+    /**
+     * Tests
+     * {@link ServletUtil#setCurrentContainer(ServletRequest, String)}.
+     */
+    @Test(expected = NoSuchContainerException.class)
+    public void testSetCurrentContainerException() {
+        Request request = createMock(Request.class);
+        ApplicationContext context = createMock(ApplicationContext.class);
+        Map<String, Object> attribs = new HashMap<String, Object>();
+
+        expect(request.getApplicationContext()).andReturn(context);
+        expect(context.getApplicationScope()).andReturn(attribs).anyTimes();
+        replay(request, context);
+        try {
+            TilesAccess.setCurrentContainer(request, "myKey");
+        } finally {
+            verify(request, context);
+        }
+    }
+
+    /**
+     * Tests
+     * {@link ServletUtil#setCurrentContainer(ServletRequest, TilesContainer)}.
+     */
+    @Test
+    public void testSetCurrentContainerWithContainer() {
+        Request request = createMock(Request.class);
+        ApplicationContext context = createMock(ApplicationContext.class);
+        TilesContainer container = createMock(TilesContainer.class);
+        Map<String, Object> attribs = new HashMap<String, Object>();
+        attribs.put("myKey", container);
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+
+        expect(context.getApplicationScope()).andReturn(attribs).anyTimes();
+        expect(request.getContext("request")).andReturn(requestScope);
+
+        replay(request, context, container);
+        TilesAccess.setCurrentContainer(request, container);
+        assertEquals(container, requestScope.get(TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME));
+        verify(request, context, container);
+    }
+
+    /**
+     * Tests
+     * {@link ServletUtil#setCurrentContainer(ServletRequest, TilesContainer)}.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testSetCurrentContainerWithContainerException() {
+        Request request = createMock(Request.class);
+        ApplicationContext context = createMock(ApplicationContext.class);
+        Map<String, Object> attribs = new HashMap<String, Object>();
+
+        expect(context.getApplicationScope()).andReturn(attribs).anyTimes();
+
+        replay(request, context);
+        try {
+            TilesAccess.setCurrentContainer(request, (TilesContainer) null);
+        } finally {
+            verify(request, context);
+        }
+    }
+
+    /**
+     * Tests {@link ServletUtil#getCurrentContainer(ServletRequest)}.
+     */
+    @Test
+    public void testGetCurrentContainer() {
+        Request request = createMock(Request.class);
+        ApplicationContext context = createMock(ApplicationContext.class);
+        TilesContainer container = createMock(TilesContainer.class);
+        Map<String, Object> attribs = new HashMap<String, Object>();
+        attribs.put("myKey", container);
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+        requestScope.put(TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME, container);
+
+        expect(request.getApplicationContext()).andReturn(context);
+        expect(context.getApplicationScope()).andReturn(attribs).anyTimes();
+        expect(request.getContext("request")).andReturn(requestScope);
+
+        replay(request, context, container);
+        assertEquals(container, TilesAccess.getCurrentContainer(request));
+        verify(request, context, container);
+    }
+
+    /**
+     * Tests {@link ServletUtil#getCurrentContainer(ServletRequest)}.
+     */
+    @Test
+    public void testGetCurrentContainerDefault() {
+        Request request = createMock(Request.class);
+        ApplicationContext context = createMock(ApplicationContext.class);
+        TilesContainer container = createMock(TilesContainer.class);
+        Map<String, Object> attribs = new HashMap<String, Object>();
+        attribs.put(TilesAccess.CONTAINER_ATTRIBUTE, container);
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+
+        expect(request.getApplicationContext()).andReturn(context);
+        expect(context.getApplicationScope()).andReturn(attribs).anyTimes();
+        expect(request.getContext("request")).andReturn(requestScope);
+
+        replay(request, context, container);
+        assertEquals(container, TilesAccess.getCurrentContainer(request));
+        verify(request, context, container);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-api/src/test/java/org/apache/tiles/preparer/PreparerExceptionTest.java b/Java-base/tiles/src/tiles-api/src/test/java/org/apache/tiles/preparer/PreparerExceptionTest.java
new file mode 100644
index 000000000..110ee79a9
--- /dev/null
+++ b/Java-base/tiles/src/tiles-api/src/test/java/org/apache/tiles/preparer/PreparerExceptionTest.java
@@ -0,0 +1,77 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.preparer;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+/**
+ * Tests {@link PreparerException}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class PreparerExceptionTest {
+
+    /**
+     * Test method for {@link PreparerException#PreparerException()}.
+     */
+    @Test
+    public void testPreparerException() {
+        PreparerException exception = new PreparerException();
+        assertNull(exception.getMessage());
+        assertNull(exception.getCause());
+    }
+
+    /**
+     * Test method for {@link PreparerException#PreparerException(java.lang.String)}.
+     */
+    @Test
+    public void testPreparerExceptionString() {
+        PreparerException exception = new PreparerException("my message");
+        assertEquals("my message", exception.getMessage());
+        assertNull(exception.getCause());
+    }
+
+    /**
+     * Test method for {@link PreparerException#PreparerException(java.lang.Throwable)}.
+     */
+    @Test
+    public void testPreparerExceptionThrowable() {
+        Throwable cause = new Throwable();
+        PreparerException exception = new PreparerException(cause);
+        assertEquals(cause.toString(), exception.getMessage());
+        assertEquals(cause, exception.getCause());
+    }
+
+    /**
+     * Test method for {@link PreparerException#PreparerException(java.lang.String, java.lang.Throwable)}.
+     */
+    @Test
+    public void testPreparerExceptionStringThrowable() {
+        Throwable cause = new Throwable();
+        PreparerException exception = new PreparerException("my message", cause);
+        assertEquals("my message", exception.getMessage());
+        assertEquals(cause, exception.getCause());
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-compat/pom.xml b/Java-base/tiles/src/tiles-compat/pom.xml
new file mode 100644
index 000000000..fae0f27ac
--- /dev/null
+++ b/Java-base/tiles/src/tiles-compat/pom.xml
@@ -0,0 +1,133 @@
+<?xml version="1.0"?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+  <parent>
+    <groupId>org.apache.tiles</groupId>
+    <artifactId>tiles-parent</artifactId>
+    <version>3.1-SNAPSHOT</version>
+  </parent>
+
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>tiles-compat</artifactId>
+  <packaging>jar</packaging>
+  <name>Tiles - Compatibility</name>
+  <description>Tiles compatibility library, to help migration from Struts-Tiles.
+  </description>
+
+  <properties>
+      <tiles.osgi.symbolicName>org.apache.tiles.compat</tiles.osgi.symbolicName>
+  </properties>
+
+  <build>
+    <resources>
+      <resource>
+        <directory>src/main/resources</directory>
+        <excludes>
+          <exclude>LICENSE.txt</exclude>
+          <exclude>NOTICE.txt</exclude>
+        </excludes>
+      </resource>
+      <resource>
+        <directory>src/main/resources</directory>
+        <includes>
+          <include>LICENSE.txt</include>
+          <include>NOTICE.txt</include>
+        </includes>
+        <targetPath>META-INF</targetPath>
+      </resource>
+    </resources>
+
+  </build>
+
+  <reporting>
+    <plugins>
+      <plugin>
+        <groupId>net.sf.dtddoc</groupId>
+        <artifactId>dtddoc-maven-plugin</artifactId>
+        <version>1.1</version>
+        <configuration>
+          <docTitle>Tiles Definition File</docTitle>
+        </configuration>
+      </plugin>
+    </plugins>
+  </reporting>
+
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.tiles</groupId>
+      <artifactId>tiles-core</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.tiles</groupId>
+      <artifactId>tiles-jsp</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-jdk14</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>jcl-over-slf4j</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>javax.servlet</groupId>
+      <artifactId>servlet-api</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.easymock</groupId>
+      <artifactId>easymock</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.shale</groupId>
+      <artifactId>shale-test</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+  </dependencies>
+
+</project>
diff --git a/Java-base/tiles/src/tiles-compat/src/main/java/org/apache/tiles/beans/MenuItem.java b/Java-base/tiles/src/tiles-compat/src/main/java/org/apache/tiles/beans/MenuItem.java
new file mode 100644
index 000000000..ca5e10773
--- /dev/null
+++ b/Java-base/tiles/src/tiles-compat/src/main/java/org/apache/tiles/beans/MenuItem.java
@@ -0,0 +1,88 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.beans;
+
+import java.io.Serializable;
+
+/**
+ * Interface for MenuItems.
+ *
+ * @see SimpleMenuItem
+ * @version $Rev$ $Date$
+ */
+public interface MenuItem extends Serializable {
+
+    /**
+     * Sets the value (i.e. the visible part) of this menu item.
+     *
+     * @param value The value of this item.
+     */
+    void setValue(String value);
+
+    /**
+     * Returns the value (i.e. the visible part) of this menu item.
+     *
+     * @return The value of this item.
+     */
+    String getValue();
+
+    /**
+     * Sets the URL of this menu item.
+     *
+     * @param link The URL of this item.
+     */
+    void setLink(String link);
+
+    /**
+     * Returns the URL of this menu item.
+     *
+     * @return The URL of this item.
+     */
+    String getLink();
+
+    /**
+     * Sets the icon URL of this menu item.
+     *
+     * @param link The icon URL.
+     */
+    void setIcon(String link);
+
+    /**
+     * Returns the icon URL of this menu item.
+     *
+     * @return The icon URL.
+     */
+    String getIcon();
+
+    /**
+     * Sets the tooltip text.
+     *
+     * @param link The tooltip text.
+     */
+    void setTooltip(String link);
+
+    /**
+     * Returns the tooltip text.
+     *
+     * @return The tooltip text.
+     */
+    String getTooltip();
+}
diff --git a/Java-base/tiles/src/tiles-compat/src/main/java/org/apache/tiles/beans/SimpleMenuItem.java b/Java-base/tiles/src/tiles-compat/src/main/java/org/apache/tiles/beans/SimpleMenuItem.java
new file mode 100644
index 000000000..a8c4b5274
--- /dev/null
+++ b/Java-base/tiles/src/tiles-compat/src/main/java/org/apache/tiles/beans/SimpleMenuItem.java
@@ -0,0 +1,157 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.beans;
+
+import java.io.Serializable;
+
+/**
+ * A MenuItem implementation.
+ * Used to read menu items in definitions.
+ *
+ * @version $Rev$ $Date$
+ */
+public class SimpleMenuItem implements MenuItem, Serializable {
+
+    /**
+     * The value of the item, i.e. what is really visible to the user.
+     */
+    private String value = null;
+
+    /**
+     * The link where the menu item points to.
+     */
+    private String link = null;
+
+    /**
+     * The (optional) icon image URL.
+     */
+    private String icon = null;
+
+    /**
+     * The (optional) tooltip text.
+     */
+    private String tooltip = null;
+
+    /**
+     * Constructor.
+     */
+    public SimpleMenuItem() {
+        super();
+    }
+
+    /**
+     * Sets the value of the item, i.e. what is really visible to the user.
+     *
+     * @param value The value of the item.
+     */
+    public void setValue(String value) {
+        this.value = value;
+    }
+
+    /**
+     * Returns the value of the item, i.e. what is really visible to the user.
+     *
+     * @return The value of the item.
+     */
+    public String getValue() {
+        return value;
+    }
+
+    /**
+     * Sets the link where the menu item points to.
+     *
+     * @param link The link.
+     */
+    public void setLink(String link) {
+        this.link = link;
+    }
+
+    /**
+     * Returns the link where the menu item points to.
+     *
+     * @return The link.
+     */
+    public String getLink() {
+        return link;
+    }
+
+    /**
+     * Sets the (optional) icon image URL.
+     *
+     * @param icon The icon URL.
+     */
+    public void setIcon(String icon) {
+        this.icon = icon;
+    }
+
+    /**
+     * Returns the (optional) icon image URL.
+     *
+     * @return The icon URL.
+     */
+    public String getIcon() {
+        return icon;
+    }
+
+    /**
+     * Sets the (optional) tooltip text.
+     *
+     * @param tooltip The tooltip text.
+     */
+    public void setTooltip(String tooltip) {
+        this.tooltip = tooltip;
+    }
+
+    /**
+     * Returns the (optional) tooltip text.
+     *
+     * @return The tooltip text.
+     */
+    public String getTooltip() {
+        return tooltip;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public String toString() {
+        StringBuilder buff = new StringBuilder("SimpleMenuItem[");
+
+        if (getValue() != null) {
+            buff.append("value=").append(getValue()).append(", ");
+        }
+
+        if (getLink() != null) {
+            buff.append("link=").append(getLink()).append(", ");
+        }
+
+        if (getTooltip() != null) {
+            buff.append("tooltip=").append(getTooltip()).append(", ");
+        }
+
+        if (getIcon() != null) {
+            buff.append("icon=").append(getIcon()).append(", ");
+        }
+
+        buff.append("]");
+        return buff.toString();
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-compat/src/main/java/org/apache/tiles/beans/package-info.java b/Java-base/tiles/src/tiles-compat/src/main/java/org/apache/tiles/beans/package-info.java
new file mode 100644
index 000000000..7ce495672
--- /dev/null
+++ b/Java-base/tiles/src/tiles-compat/src/main/java/org/apache/tiles/beans/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * Classes to work with Tiles menu items and beans.
+ */
+package org.apache.tiles.beans;
diff --git a/Java-base/tiles/src/tiles-compat/src/main/java/org/apache/tiles/compat/definition/digester/CompatibilityDigesterDefinitionsReader.java b/Java-base/tiles/src/tiles-compat/src/main/java/org/apache/tiles/compat/definition/digester/CompatibilityDigesterDefinitionsReader.java
new file mode 100644
index 000000000..7a5f597a1
--- /dev/null
+++ b/Java-base/tiles/src/tiles-compat/src/main/java/org/apache/tiles/compat/definition/digester/CompatibilityDigesterDefinitionsReader.java
@@ -0,0 +1,264 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.compat.definition.digester;
+
+import org.apache.commons.digester.Digester;
+import org.apache.commons.digester.Rule;
+import org.apache.tiles.Attribute;
+import org.apache.tiles.beans.SimpleMenuItem;
+import org.apache.tiles.definition.digester.DigesterDefinitionsReader;
+import org.xml.sax.Attributes;
+
+/**
+ * Digester reader that can read Tiles 1.1, 1.2, 1.3, 1.4 and 2.0 files.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.1.0
+ */
+public class CompatibilityDigesterDefinitionsReader extends
+        DigesterDefinitionsReader {
+
+    /**
+     * Intercepts a &lt;item&gt; tag.
+     */
+    private static final String ADD_WILDCARD = "*/item";
+
+    /**
+     * Intercepts a &lt;bean&gt; tag.
+     */
+    private static final String BEAN_TAG = "*/bean";
+
+    /**
+     * The set of public identifiers, and corresponding resource names for the
+     * versions of the configuration file DTDs we know about. There <strong>MUST</strong>
+     * be an even number of Strings in this list!
+     *
+     * @since 2.1.0
+     */
+    protected String[] registrations;
+
+    /** {@inheritDoc} */
+    @Override
+    protected void initSyntax(Digester digester) {
+        super.initSyntax(digester);
+        initDigesterForComponentsDefinitionsSyntax(digester);
+        initDigesterForInstancesSyntax(digester);
+        initDigesterForTilesDefinitionsSyntax(digester);
+        initDigesterForBeans(digester);
+    }
+
+    /**
+     * Init digester for components syntax. This is an old set of rules, left
+     * for backward compatibility.
+     *
+     * @param digester Digester instance to use.
+     */
+    private void initDigesterForComponentsDefinitionsSyntax(Digester digester) {
+        // Common constants
+        String definitionTag = "component-definitions/definition";
+
+        String putTag = definitionTag + "/put";
+
+        String listTag = definitionTag + "/putList";
+
+        String addListElementTag = listTag + "/add";
+
+        // syntax rules
+        digester.addObjectCreate(definitionTag, DEFINITION_HANDLER_CLASS);
+        digester.addRule(definitionTag, new FillDefinitionRule());
+        digester.addSetNext(definitionTag, "addDefinition",
+                DEFINITION_HANDLER_CLASS);
+        // put / putAttribute rules
+        digester.addObjectCreate(putTag, PUT_ATTRIBUTE_HANDLER_CLASS);
+        digester.addRule(putTag, new FillAttributeRule());
+        digester.addRule(putTag, new PutAttributeRule());
+        // list rules
+        digester.addObjectCreate(listTag, LIST_HANDLER_CLASS);
+        digester.addSetProperties(listTag);
+        digester.addRule(listTag, new PutAttributeRule());
+        // list elements rules
+        // We use Attribute class to avoid rewriting a new class.
+        // Name part can't be used in listElement attribute.
+        digester.addObjectCreate(addListElementTag, PUT_ATTRIBUTE_HANDLER_CLASS);
+        digester.addRule(addListElementTag, new FillAttributeRule());
+        digester.addSetNext(addListElementTag, "add",
+                PUT_ATTRIBUTE_HANDLER_CLASS);
+    }
+
+    /**
+     * Init digester for Tiles syntax. Same as components, but with first
+     * element = tiles-definitions
+     *
+     * @param digester Digester instance to use.
+     */
+    private void initDigesterForTilesDefinitionsSyntax(Digester digester) {
+        // Common constants
+        String definitionTag = "tiles-definitions/definition";
+
+        String putTag = definitionTag + "/put";
+
+        // String LIST_TAG = DEFINITION_TAG + "/putList";
+        // List tag value
+        String listTag = "putList";
+        String definitionListTag = definitionTag + "/" + listTag;
+        // Tag value for adding an element in a list
+        String addListElementTag = "*/" + listTag + "/add";
+
+        // put / putAttribute rules
+        // Rules for a same pattern are called in order, but rule.end() are
+        // called
+        // in reverse order.
+        // SetNext and CallMethod use rule.end() method. So, placing SetNext in
+        // first position ensure it will be called last (sic).
+        digester.addObjectCreate(putTag, PUT_ATTRIBUTE_HANDLER_CLASS);
+        digester.addRule(putTag, new FillAttributeRule());
+        digester.addRule(putTag, new PutAttributeRule());
+        // Definition level list rules
+        // This is rules for lists nested in a definition
+        digester.addObjectCreate(definitionListTag, LIST_HANDLER_CLASS);
+        digester.addSetProperties(definitionListTag);
+        digester.addRule(definitionListTag, new PutAttributeRule());
+        // list elements rules
+        // We use Attribute class to avoid rewriting a new class.
+        // Name part can't be used in listElement attribute.
+        digester.addObjectCreate(addListElementTag, PUT_ATTRIBUTE_HANDLER_CLASS);
+        digester.addRule(addListElementTag, new FillAttributeRule());
+        digester.addSetNext(addListElementTag, "add",
+                PUT_ATTRIBUTE_HANDLER_CLASS);
+
+        // nested list elements rules
+        // Create a list handler, and add it to parent list
+        String nestedList = "*/" + listTag + "/" + listTag;
+        digester.addObjectCreate(nestedList, LIST_HANDLER_CLASS);
+        digester.addSetProperties(nestedList);
+        digester.addSetNext(nestedList, "add", PUT_ATTRIBUTE_HANDLER_CLASS);
+    }
+
+    /**
+     * Init digester in order to parse instances definition file syntax.
+     * Instances is an old name for "definition". This method is left for
+     * backwards compatibility.
+     *
+     * @param digester Digester instance to use.
+     */
+    private void initDigesterForInstancesSyntax(Digester digester) {
+        // Build a digester to process our configuration resource
+        String instanceTag = "component-instances/instance";
+
+        String putTag = instanceTag + "/put";
+        String putAttributeTag = instanceTag + "/putAttribute";
+
+        String listTag = instanceTag + "/putList";
+
+        String addListElementTag = listTag + "/add";
+
+        // component instance rules
+        digester.addObjectCreate(instanceTag, DEFINITION_HANDLER_CLASS);
+        digester.addRule(instanceTag, new FillDefinitionRule());
+        digester
+                .addSetNext(instanceTag, "addDefinition", DEFINITION_HANDLER_CLASS);
+        // put / putAttribute rules
+        digester.addObjectCreate(putAttributeTag, PUT_ATTRIBUTE_HANDLER_CLASS);
+        digester.addRule(putTag, new FillAttributeRule());
+        digester.addRule(putTag, new PutAttributeRule());
+        // put / putAttribute rules
+        digester.addObjectCreate(putTag, PUT_ATTRIBUTE_HANDLER_CLASS);
+        digester.addSetProperties(putTag);
+        digester.addRule(putTag, new PutAttributeRule());
+        // list rules
+        digester.addObjectCreate(listTag, PUT_ATTRIBUTE_HANDLER_CLASS);
+        digester.addSetProperties(listTag);
+        digester.addRule(listTag, new PutAttributeRule());
+        // list elements rules
+        // We use Attribute class to avoid rewriting a new class.
+        // Name part can't be used in listElement attribute.
+        digester.addObjectCreate(addListElementTag, PUT_ATTRIBUTE_HANDLER_CLASS);
+        digester.addRule(addListElementTag, new FillAttributeRule());
+        digester.addSetNext(addListElementTag, "add", PUT_ATTRIBUTE_HANDLER_CLASS);
+    }
+
+    /**
+     * Init digester for Tiles syntax with first element = tiles-definitions.
+     *
+     * @param digester Digester instance to use.
+     */
+    private void initDigesterForBeans(Digester digester) {
+
+        // item elements rules
+        // We use Attribute class to avoid rewriting a new class.
+        // Name part can't be used in listElement attribute.
+        //String ADD_WILDCARD = LIST_TAG + "/addItem";
+        // non String ADD_WILDCARD = LIST_TAG + "/addx*";
+        String menuItemDefaultClass = SimpleMenuItem.class.getName();
+        digester.addObjectCreate(ADD_WILDCARD, menuItemDefaultClass, "classtype");
+        digester.addSetProperties(ADD_WILDCARD);
+        digester.addRule(ADD_WILDCARD, new SetValueToAttributeRule());
+        digester.addSetNext(ADD_WILDCARD, "add", PUT_ATTRIBUTE_HANDLER_CLASS);
+
+        // bean elements rules
+        String beanDefaultClass = SimpleMenuItem.class.getName();
+        digester.addObjectCreate(BEAN_TAG, beanDefaultClass, "classtype");
+        digester.addSetProperties(BEAN_TAG);
+        digester.addRule(BEAN_TAG, new SetValueToAttributeRule());
+        digester.addSetNext(BEAN_TAG, "add", PUT_ATTRIBUTE_HANDLER_CLASS);
+
+        // Set properties to surrounding element
+        digester.addSetProperty(BEAN_TAG + "/set-property", "property", "value");
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected String[] getRegistrations() {
+        if (registrations == null) {
+            registrations = new String[] {
+                "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN",
+                "/org/apache/tiles/resources/tiles-config_3_0.dtd",
+                "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN",
+                "/org/apache/tiles/compat/resources/tiles-config_2_0.dtd",
+                "-//Apache Software Foundation//DTD Tiles Configuration 2.1//EN",
+                "/org/apache/tiles/compat/resources/tiles-config_2_1.dtd",
+                "-//Apache Software Foundation//DTD Tiles Configuration 1.1//EN",
+                "/org/apache/tiles/compat/resources/tiles-config_1_1.dtd",
+                "-//Apache Software Foundation//DTD Tiles Configuration 1.3//EN",
+                "/org/apache/tiles/compat/resources/tiles-config_1_3.dtd",
+                "-//Apache Software Foundation//DTD Tiles Configuration 1.4//EN",
+                "/org/apache/tiles/compat/resources/tiles-config_1_4.dtd"};
+        }
+        return registrations;
+    }
+
+    /**
+     * Digester rule to manage assignment of an object as an attribute value.
+     *
+     * @since 3.0.0
+     */
+    public static class SetValueToAttributeRule extends Rule {
+
+        /** {@inheritDoc} */
+        @Override
+        public void begin(String namespace, String name, Attributes attributes) {
+            Object obj = digester.pop();
+            Attribute attribute = new Attribute(obj);
+            digester.push(attribute);
+        }
+    }
+}
diff --git a/Java-base/tiles/src/tiles-compat/src/main/java/org/apache/tiles/compat/definition/digester/package-info.java b/Java-base/tiles/src/tiles-compat/src/main/java/org/apache/tiles/compat/definition/digester/package-info.java
new file mode 100644
index 000000000..a3826dbd5
--- /dev/null
+++ b/Java-base/tiles/src/tiles-compat/src/main/java/org/apache/tiles/compat/definition/digester/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * Contains code to read old-format Tiles definition files.
+ */
+package org.apache.tiles.compat.definition.digester;
diff --git a/Java-base/tiles/src/tiles-compat/src/main/java/org/apache/tiles/compat/preparer/CompatibilityPreparerFactory.java b/Java-base/tiles/src/tiles-compat/src/main/java/org/apache/tiles/compat/preparer/CompatibilityPreparerFactory.java
new file mode 100644
index 000000000..300aafaf5
--- /dev/null
+++ b/Java-base/tiles/src/tiles-compat/src/main/java/org/apache/tiles/compat/preparer/CompatibilityPreparerFactory.java
@@ -0,0 +1,49 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.compat.preparer;
+
+import org.apache.tiles.preparer.ViewPreparer;
+import org.apache.tiles.preparer.factory.BasicPreparerFactory;
+
+/**
+ * Factory used to instantiate preparers in a Struts 1 / Tiles 2 environment.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.1.0
+ */
+public class CompatibilityPreparerFactory extends BasicPreparerFactory {
+
+    /** {@inheritDoc} */
+    @Override
+    protected ViewPreparer createPreparer(String name) {
+        ViewPreparer retValue;
+
+        if (name.startsWith("/")) {
+            retValue = new UrlPreparer(name);
+        } else {
+            retValue = super.createPreparer(name);
+        }
+
+        return retValue;
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-compat/src/main/java/org/apache/tiles/compat/preparer/UrlPreparer.java b/Java-base/tiles/src/tiles-compat/src/main/java/org/apache/tiles/compat/preparer/UrlPreparer.java
new file mode 100644
index 000000000..0082d2e9b
--- /dev/null
+++ b/Java-base/tiles/src/tiles-compat/src/main/java/org/apache/tiles/compat/preparer/UrlPreparer.java
@@ -0,0 +1,72 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.compat.preparer;
+
+import java.io.IOException;
+
+import org.apache.tiles.AttributeContext;
+import org.apache.tiles.preparer.PreparerException;
+import org.apache.tiles.preparer.ViewPreparer;
+import org.apache.tiles.request.Request;
+import org.apache.tiles.request.DispatchRequest;
+
+/**
+ * Uses a URL that acts as a preparer. When
+ * {@link org.apache.tiles.preparer.factory.factory.ViewPreparer#execute(Request, AttributeContext)}
+ * is called, the URL is got, but its response is discarded.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.1.0
+ */
+public class UrlPreparer implements ViewPreparer {
+
+    /**
+     * The URL to be used as a preparer.
+     */
+    private String url;
+
+    /**
+     * Constructor.
+     *
+     * @param url The URL to be used as a preparer.
+     */
+    public UrlPreparer(String url) {
+        this.url = url;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void execute(Request tilesContext,
+            AttributeContext attributeContext) {
+
+        if (tilesContext instanceof DispatchRequest) {
+            try {
+                ((DispatchRequest) tilesContext).include(url);
+            } catch (IOException e) {
+                throw new PreparerException("The inclusion of the URL " + url
+                        + " threw an I/O exception", e);
+            }
+        } else {
+            throw new PreparerException("This preparer is restricted to web environments");
+        }
+    }
+}
diff --git a/Java-base/tiles/src/tiles-compat/src/main/java/org/apache/tiles/compat/preparer/package-info.java b/Java-base/tiles/src/tiles-compat/src/main/java/org/apache/tiles/compat/preparer/package-info.java
new file mode 100644
index 000000000..e84df12a7
--- /dev/null
+++ b/Java-base/tiles/src/tiles-compat/src/main/java/org/apache/tiles/compat/preparer/package-info.java
@@ -0,0 +1,28 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * <p>"View preparers" are objects that allows the "preparation" of a Tiles artifact
+ * (definition, template or attribute) before it is rendered.</p>
+ * <p>This package contains "compatibility" preparers, i.e. ViewPreparers that are
+ * compatibile with Tiles 1 "controllers".</p>
+ */
+package org.apache.tiles.compat.preparer;
+
diff --git a/Java-base/tiles/src/tiles-compat/src/main/resources/LICENSE.txt b/Java-base/tiles/src/tiles-compat/src/main/resources/LICENSE.txt
new file mode 100644
index 000000000..d64569567
--- /dev/null
+++ b/Java-base/tiles/src/tiles-compat/src/main/resources/LICENSE.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/Java-base/tiles/src/tiles-compat/src/main/resources/NOTICE.txt b/Java-base/tiles/src/tiles-compat/src/main/resources/NOTICE.txt
new file mode 100644
index 000000000..1f13ff856
--- /dev/null
+++ b/Java-base/tiles/src/tiles-compat/src/main/resources/NOTICE.txt
@@ -0,0 +1,6 @@
+   Apache Tiles
+   Copyright 1999-2009 The Apache Software Foundation
+
+   This product includes software developed at
+   The Apache Software Foundation (http://www.apache.org/).
+
diff --git a/Java-base/tiles/src/tiles-compat/src/main/resources/org/apache/tiles/compat/resources/tiles-config_1_1.dtd b/Java-base/tiles/src/tiles-compat/src/main/resources/org/apache/tiles/compat/resources/tiles-config_1_1.dtd
new file mode 100644
index 000000000..0a4db134b
--- /dev/null
+++ b/Java-base/tiles/src/tiles-compat/src/main/resources/org/apache/tiles/compat/resources/tiles-config_1_1.dtd
@@ -0,0 +1,299 @@
+<!--
+    $Id$
+
+    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.
+-->
+<!--
+     DTD for the Tile Definition File, Version 1.1
+
+     To support validation of your configuration file, include the following
+     DOCTYPE element at the beginning (after the "xml" declaration):
+
+     <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 1.1//EN"
+       "http://struts.apache.org/dtds/tiles-config_1_1.dtd">
+
+     $Id$
+-->
+
+
+<!-- ========== Defined Types ============================================= -->
+
+
+<!-- A "Boolean" is the string representation of a boolean (true or false)
+     variable.
+-->
+<!ENTITY % Boolean "(true|false)">
+
+
+<!-- A "ContentType" is the content type of an attribute passed to a tile
+     component.
+-->
+<!ENTITY % ContentType "(string|page|template|definition)">
+
+<!-- A "ClassName" is the fully qualified name of a Java class that is
+     instantiated to provide the functionality of the enclosing element.
+-->
+<!ENTITY % ClassName "CDATA">
+
+<!-- A "RequestPath" is an module-relative URI path, beginning with a
+     slash, that identifies a mapped resource (such as a JSP page or a servlet)
+     within this web application.
+-->
+<!ENTITY % RequestPath "CDATA">
+
+<!-- A "DefinitionName" is the unique identifier of a definition. This identifier
+     is a logical name used to reference the definition.
+-->
+<!ENTITY % DefinitionName "CDATA">
+
+<!-- A "BeanName" is the identifier of a JavaBean, such as a form bean,
+     and also serves as the name of the corresponding scripting variable
+     and the name of the JSP attribute under which the bean is accessed.
+     Therefore, it must conform to the rules for a Java identifier.
+-->
+<!ENTITY % BeanName "CDATA">
+
+<!-- A "PropName" is the name of a JavaBeans property, and must begin with
+     a lower case letter and contain only characters that are legal in a
+     Java identifier.
+-->
+<!ENTITY % PropName "CDATA">
+
+<!-- A "Location" is a relative path, delimited by "/" characters, that
+     defines the location of a resource relative to the location of the
+     configuration file itself.
+-->
+<!ENTITY % Location "#PCDATA">
+
+
+
+<!-- ========== Top Level Elements ======================================== -->
+
+
+  <!-- deprecated: use tiles-definitions instead.-->
+<!ELEMENT component-definitions (definition+)>
+
+<!-- The "tiles-definitions" element is the root of the configuration file
+     hierarchy, and contains nested elements for all of the other
+     configuration settings.
+-->
+<!ELEMENT tiles-definitions (definition+)>
+
+<!-- The "definition" element describes a definition that can be inserted in a jsp
+     page. This definition is identified by its logical name. A definition allows
+     to define all the attributes that can be set in <insert> tag from a jsp page.
+
+     controllerClass The fully qualified Java class name of the controller
+                     subclass to call immediately before the tiles is inserted.
+                     Only one of controllerClass or controllerUrl should be
+                     specified.
+
+     controllerUrl   The context-relative path to the resource used as controller
+                     called immediately before the tiles is inserted.
+                     Only one of controllerClass or controllerUrl should be
+                     specified.
+
+     extends         Name of a definition that is used as ancestor of this definition.
+                     All attributes from the ancestor are available to the new
+                     definition. Any attribute inherited from the ancestor can
+                     be overloaded by providing a new value.
+
+     name            The unique identifier for this definition.
+
+     page            Same as path.
+
+     path            The context-relative path to the resource used as tiles to
+                     insert. This tiles will be inserted and a tiles context
+                     containing appropriate attributes will be available.
+
+     role            Security role name that is allowed access to this definition
+                     object. The definition is inserted only if the role name is
+                     allowed.
+
+     template        Same as path. For compatibility with the template tag library.
+-->
+<!ELEMENT definition (icon?, display-name?, description?, put*, putList*)>
+<!ATTLIST definition       id               ID               #IMPLIED>
+<!ATTLIST definition       controllerClass  %ClassName;      #IMPLIED>
+<!ATTLIST definition       controllerUrl    %RequestPath;    #IMPLIED>
+<!ATTLIST definition       extends          %DefinitionName; #IMPLIED>
+<!ATTLIST definition       name             %DefinitionName; #REQUIRED>
+<!ATTLIST definition       page             %RequestPath;    #IMPLIED>
+<!ATTLIST definition       path             %RequestPath;    #IMPLIED>
+<!ATTLIST definition       role             CDATA            #IMPLIED>
+<!ATTLIST definition       template         %RequestPath;    #IMPLIED>
+
+
+<!-- The "put" element describes an attribute of a definition. It allows to
+     specify the tiles attribute name and its value. The tiles value can be
+     specified as an xml attribute, or in the body of the <put> tag.
+
+     content         Same as value. For compatibility with the template tag library.
+
+     direct          Same as type="string". For compatibility with the template
+                     tag library.
+
+     name            The unique identifier for this put.
+
+     type            The type of the value. Can be: string, page, template or definition.
+                     By default, no type is associated to a value. If a type is
+                     associated, it will be used as a hint to process the value
+                     when the attribute will be used in the inserted tiles.
+
+     value           The value associated to this tiles attribute. The value should
+                     be specified with this tag attribute, or in the body of the tag.
+-->
+<!ELEMENT put (#PCDATA)>
+<!ATTLIST put              id               ID              #IMPLIED>
+<!ATTLIST put              content          CDATA           #IMPLIED>
+<!ATTLIST put              direct           %Boolean;       #IMPLIED>
+<!ATTLIST put              name             CDATA           #REQUIRED>
+<!ATTLIST put              type             %ContentType;   #IMPLIED>
+<!ATTLIST put              value            CDATA           #IMPLIED>
+
+
+<!-- The "putList" element describes a list attribute of a definition. It allows to
+     specify an attribute that is a java List containing any kind of values. In
+     the config file, the list elements are specified by nested <add>, <item> or
+     <putList>.
+
+     name            The unique identifier for this put list.
+-->
+<!ELEMENT putList ( (add* | item* | bean* | putList*)+) >
+<!ATTLIST putList          id               ID              #IMPLIED>
+<!ATTLIST putList          name             CDATA           #REQUIRED>
+
+<!-- ========== Subordinate Elements ====================================== -->
+
+<!-- The "add" element describes an element of a list. It is similar to the
+     <put> element.
+
+     content         Same as value. For compatibility with the template tag library.
+
+     direct          Same as type="string". For compatibility with the template
+                     tag library.
+
+     type            The type of the value. Can be: string, page, template or definition.
+                     By default, no type is associated to a value. If a type is
+                     associated, it will be used as a hint to process the value
+                     when the attribute will be used in the inserted tiles.
+
+     value           The value associated to this tiles attribute. The value should
+                     be specified with this tag attribute, or in the body of the tag.
+-->
+<!ELEMENT add (#PCDATA)>
+<!ATTLIST add              id               ID              #IMPLIED>
+<!ATTLIST add              content          CDATA           #IMPLIED>
+<!ATTLIST add              direct           %Boolean;       #IMPLIED>
+<!ATTLIST add              type             %ContentType;   #IMPLIED>
+<!ATTLIST add              value            CDATA           #IMPLIED>
+
+
+<!-- The "bean" element describes an element of a list. It create a bean of the
+     specified java classtype. This bean is initialized with appropriate nested
+     <set-property>.
+
+     classtype       The fully qualified classname for this bean.
+-->
+<!ELEMENT bean (set-property*)>
+<!ATTLIST bean             id               ID              #IMPLIED>
+<!ATTLIST bean             classtype        %ClassName;     #REQUIRED>
+
+<!-- The "set-property" element specifies the method name and initial value of
+     a bean property. When the object representing
+     the surrounding element is instantiated, the accessor for the indicated
+     property is called and passed the indicated value.
+
+     property        Name of the JavaBeans property whose setter method
+                     will be called.
+
+     value           String representation of the value to which this
+                     property will be set, after suitable type conversion
+-->
+<!ELEMENT set-property   EMPTY>
+<!ATTLIST set-property   id             ID              #IMPLIED>
+<!ATTLIST set-property   property       %PropName;      #REQUIRED>
+<!ATTLIST set-property   value          CDATA           #REQUIRED>
+
+
+<!-- The "item" element describes an element of a list. It create a bean added as
+     element to the list. Each bean can contain different properties: value, link,
+     icon, tooltip. These properties are to be interpreted by the jsp page using
+     them.
+     By default the bean is of type
+     "org.apache.struts.tiles.beans.SimpleMenuItem". This bean is useful to
+     create a list of beans used as menu items.
+
+     classtype       The fully qualified classtype for this bean.
+                     If specified, the classtype must be a subclass of the interface
+                     "org.apache.struts.tiles.beans.MenuItem".
+
+     icon            The bean 'icon' property.
+
+     link            The bean 'link' property.
+
+     tooltip         The bean 'tooltip' property.
+
+     value           The bean 'value' property.
+-->
+<!ELEMENT item (#PCDATA)>
+<!ATTLIST item             id               ID              #IMPLIED>
+<!ATTLIST item             classtype        %ClassName;     #IMPLIED>
+<!ATTLIST item             icon             CDATA           #IMPLIED>
+<!ATTLIST item             link             CDATA           #REQUIRED>
+<!ATTLIST item             tooltip          CDATA           #IMPLIED>
+<!ATTLIST item             value            CDATA           #REQUIRED>
+
+
+<!-- ========== Info Elements ====================================== -->
+
+<!-- The "description" element contains descriptive (paragraph length) text
+     about the surrounding element, suitable for use in GUI tools.
+-->
+<!ELEMENT description    (#PCDATA)>
+<!ATTLIST description    id             ID              #IMPLIED>
+
+
+<!-- The "display-name" element contains a short (one line) description of
+     the surrounding element, suitable for use in GUI tools.
+-->
+<!ELEMENT display-name (#PCDATA)>
+<!ATTLIST display-name   id             ID              #IMPLIED>
+
+
+<!-- The "icon" element contains a small-icon and large-icon element which
+     specify the location, relative to the Struts configuration file, for small
+     and large images used to represent the surrounding element in GUI tools.
+-->
+<!ELEMENT icon           (small-icon?, large-icon?)>
+<!ATTLIST icon           id             ID              #IMPLIED>
+
+
+<!-- The "large-icon" element specifies the location, relative to the Struts
+     configuration file, of a resource containing a large (32x32 pixel)
+     icon image.
+-->
+<!ELEMENT large-icon     (%Location;)>
+<!ATTLIST large-icon     id             ID              #IMPLIED>
+
+
+<!-- The "small-icon" element specifies the location, relative to the Struts
+     configuration file, of a resource containing a small (16x16 pixel)
+     icon image.
+-->
+<!ELEMENT small-icon     (%Location;)>
+<!ATTLIST small-icon     id             ID              #IMPLIED>
diff --git a/Java-base/tiles/src/tiles-compat/src/main/resources/org/apache/tiles/compat/resources/tiles-config_1_3.dtd b/Java-base/tiles/src/tiles-compat/src/main/resources/org/apache/tiles/compat/resources/tiles-config_1_3.dtd
new file mode 100644
index 000000000..a532cb07e
--- /dev/null
+++ b/Java-base/tiles/src/tiles-compat/src/main/resources/org/apache/tiles/compat/resources/tiles-config_1_3.dtd
@@ -0,0 +1,299 @@
+<!--
+    $Id$
+
+    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.
+-->
+<!--
+     DTD for the Tile Definition File, Version 1.3
+
+     To support validation of your configuration file, include the following
+     DOCTYPE element at the beginning (after the "xml" declaration):
+
+     <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 1.3//EN"
+       "http://struts.apache.org/dtds/tiles-config_1_3.dtd">
+
+     $Id$
+-->
+
+
+<!-- ========== Defined Types ============================================= -->
+
+
+<!-- A "Boolean" is the string representation of a boolean (true or false)
+     variable.
+-->
+<!ENTITY % Boolean "(true|false)">
+
+
+<!-- A "ContentType" is the content type of an attribute passed to a tile
+     component.
+-->
+<!ENTITY % ContentType "(string|page|template|definition)">
+
+<!-- A "ClassName" is the fully qualified name of a Java class that is
+     instantiated to provide the functionality of the enclosing element.
+-->
+<!ENTITY % ClassName "CDATA">
+
+<!-- A "RequestPath" is an module-relative URI path, beginning with a
+     slash, that identifies a mapped resource (such as a JSP page or a servlet)
+     within this web application.
+-->
+<!ENTITY % RequestPath "CDATA">
+
+<!-- A "DefinitionName" is the unique identifier of a definition. This identifier
+     is a logical name used to reference the definition.
+-->
+<!ENTITY % DefinitionName "CDATA">
+
+<!-- A "BeanName" is the identifier of a JavaBean, such as a form bean,
+     and also serves as the name of the corresponding scripting variable
+     and the name of the JSP attribute under which the bean is accessed.
+     Therefore, it must conform to the rules for a Java identifier.
+-->
+<!ENTITY % BeanName "CDATA">
+
+<!-- A "PropName" is the name of a JavaBeans property, and must begin with
+     a lower case letter and contain only characters that are legal in a
+     Java identifier.
+-->
+<!ENTITY % PropName "CDATA">
+
+<!-- A "Location" is a relative path, delimited by "/" characters, that
+     defines the location of a resource relative to the location of the
+     configuration file itself.
+-->
+<!ENTITY % Location "#PCDATA">
+
+
+
+<!-- ========== Top Level Elements ======================================== -->
+
+
+  <!-- deprecated: use tiles-definitions instead.-->
+<!ELEMENT component-definitions (definition+)>
+
+<!-- The "tiles-definitions" element is the root of the configuration file
+     hierarchy, and contains nested elements for all of the other
+     configuration settings.
+-->
+<!ELEMENT tiles-definitions (definition+)>
+
+<!-- The "definition" element describes a definition that can be inserted in a jsp
+     page. This definition is identified by its logical name. A definition allows
+     to define all the attributes that can be set in <insert> tag from a jsp page.
+
+     controllerClass The fully qualified Java class name of the controller
+                     subclass to call immediately before the tiles is inserted.
+                     Only one of controllerClass or controllerUrl should be
+                     specified.
+
+     controllerUrl   The context-relative path to the resource used as controller
+                     called immediately before the tiles is inserted.
+                     Only one of controllerClass or controllerUrl should be
+                     specified.
+
+     extends         Name of a definition that is used as ancestor of this definition.
+                     All attributes from the ancestor are available to the new
+                     definition. Any attribute inherited from the ancestor can
+                     be overloaded by providing a new value.
+
+     name            The unique identifier for this definition.
+
+     page            Same as path.
+
+     path            The context-relative path to the resource used as tiles to
+                     insert. This tiles will be inserted and a tiles context
+                     containing appropriate attributes will be available.
+
+     role            Security role name that is allowed access to this definition
+                     object. The definition is inserted only if the role name is
+                     allowed.
+
+     template        Same as path. For compatibility with the template tag library.
+-->
+<!ELEMENT definition (icon?, display-name?, description?, put*, putList*)>
+<!ATTLIST definition       id               ID               #IMPLIED>
+<!ATTLIST definition       controllerClass  %ClassName;      #IMPLIED>
+<!ATTLIST definition       controllerUrl    %RequestPath;    #IMPLIED>
+<!ATTLIST definition       extends          %DefinitionName; #IMPLIED>
+<!ATTLIST definition       name             %DefinitionName; #REQUIRED>
+<!ATTLIST definition       page             %RequestPath;    #IMPLIED>
+<!ATTLIST definition       path             %RequestPath;    #IMPLIED>
+<!ATTLIST definition       role             CDATA            #IMPLIED>
+<!ATTLIST definition       template         %RequestPath;    #IMPLIED>
+
+
+<!-- The "put" element describes an attribute of a definition. It allows to
+     specify the tiles attribute name and its value. The tiles value can be
+     specified as an xml attribute, or in the body of the <put> tag.
+
+     content         Same as value. For compatibility with the template tag library.
+
+     direct          Same as type="string". For compatibility with the template
+                     tag library.
+
+     name            The unique identifier for this put.
+
+     type            The type of the value. Can be: string, page, template or definition.
+                     By default, no type is associated to a value. If a type is
+                     associated, it will be used as a hint to process the value
+                     when the attribute will be used in the inserted tiles.
+
+     value           The value associated to this tiles attribute. The value should
+                     be specified with this tag attribute, or in the body of the tag.
+-->
+<!ELEMENT put (#PCDATA)>
+<!ATTLIST put              id               ID              #IMPLIED>
+<!ATTLIST put              content          CDATA           #IMPLIED>
+<!ATTLIST put              direct           %Boolean;       #IMPLIED>
+<!ATTLIST put              name             CDATA           #REQUIRED>
+<!ATTLIST put              type             %ContentType;   #IMPLIED>
+<!ATTLIST put              value            CDATA           #IMPLIED>
+
+
+<!-- The "putList" element describes a list attribute of a definition. It allows to
+     specify an attribute that is a java List containing any kind of values. In
+     the config file, the list elements are specified by nested <add>, <item> or
+     <putList>.
+
+     name            The unique identifier for this put list.
+-->
+<!ELEMENT putList ( (add* | item* | bean* | putList*)+) >
+<!ATTLIST putList          id               ID              #IMPLIED>
+<!ATTLIST putList          name             CDATA           #REQUIRED>
+
+<!-- ========== Subordinate Elements ====================================== -->
+
+<!-- The "add" element describes an element of a list. It is similar to the
+     <put> element.
+
+     content         Same as value. For compatibility with the template tag library.
+
+     direct          Same as type="string". For compatibility with the template
+                     tag library.
+
+     type            The type of the value. Can be: string, page, template or definition.
+                     By default, no type is associated to a value. If a type is
+                     associated, it will be used as a hint to process the value
+                     when the attribute will be used in the inserted tiles.
+
+     value           The value associated to this tiles attribute. The value should
+                     be specified with this tag attribute, or in the body of the tag.
+-->
+<!ELEMENT add (#PCDATA)>
+<!ATTLIST add              id               ID              #IMPLIED>
+<!ATTLIST add              content          CDATA           #IMPLIED>
+<!ATTLIST add              direct           %Boolean;       #IMPLIED>
+<!ATTLIST add              type             %ContentType;   #IMPLIED>
+<!ATTLIST add              value            CDATA           #IMPLIED>
+
+
+<!-- The "bean" element describes an element of a list. It create a bean of the
+     specified java classtype. This bean is initialized with appropriate nested
+     <set-property>.
+
+     classtype       The fully qualified classname for this bean.
+-->
+<!ELEMENT bean (set-property*)>
+<!ATTLIST bean             id               ID              #IMPLIED>
+<!ATTLIST bean             classtype        %ClassName;     #REQUIRED>
+
+<!-- The "set-property" element specifies the method name and initial value of
+     a bean property. When the object representing
+     the surrounding element is instantiated, the accessor for the indicated
+     property is called and passed the indicated value.
+
+     property        Name of the JavaBeans property whose setter method
+                     will be called.
+
+     value           String representation of the value to which this
+                     property will be set, after suitable type conversion
+-->
+<!ELEMENT set-property   EMPTY>
+<!ATTLIST set-property   id             ID              #IMPLIED>
+<!ATTLIST set-property   property       %PropName;      #REQUIRED>
+<!ATTLIST set-property   value          CDATA           #REQUIRED>
+
+
+<!-- The "item" element describes an element of a list. It create a bean added as
+     element to the list. Each bean can contain different properties: value, link,
+     icon, tooltip. These properties are to be interpreted by the jsp page using
+     them.
+     By default the bean is of type
+     "org.apache.struts.tiles.beans.SimpleMenuItem". This bean is useful to
+     create a list of beans used as menu items.
+
+     classtype       The fully qualified classtype for this bean.
+                     If specified, the classtype must be a subclass of the interface
+                     "org.apache.struts.tiles.beans.MenuItem".
+
+     icon            The bean 'icon' property.
+
+     link            The bean 'link' property.
+
+     tooltip         The bean 'tooltip' property.
+
+     value           The bean 'value' property.
+-->
+<!ELEMENT item (#PCDATA)>
+<!ATTLIST item             id               ID              #IMPLIED>
+<!ATTLIST item             classtype        %ClassName;     #IMPLIED>
+<!ATTLIST item             icon             CDATA           #IMPLIED>
+<!ATTLIST item             link             CDATA           #REQUIRED>
+<!ATTLIST item             tooltip          CDATA           #IMPLIED>
+<!ATTLIST item             value            CDATA           #REQUIRED>
+
+
+<!-- ========== Info Elements ====================================== -->
+
+<!-- The "description" element contains descriptive (paragraph length) text
+     about the surrounding element, suitable for use in GUI tools.
+-->
+<!ELEMENT description    (#PCDATA)>
+<!ATTLIST description    id             ID              #IMPLIED>
+
+
+<!-- The "display-name" element contains a short (one line) description of
+     the surrounding element, suitable for use in GUI tools.
+-->
+<!ELEMENT display-name (#PCDATA)>
+<!ATTLIST display-name   id             ID              #IMPLIED>
+
+
+<!-- The "icon" element contains a small-icon and large-icon element which
+     specify the location, relative to the Struts configuration file, for small
+     and large images used to represent the surrounding element in GUI tools.
+-->
+<!ELEMENT icon           (small-icon?, large-icon?)>
+<!ATTLIST icon           id             ID              #IMPLIED>
+
+
+<!-- The "large-icon" element specifies the location, relative to the Struts
+     configuration file, of a resource containing a large (32x32 pixel)
+     icon image.
+-->
+<!ELEMENT large-icon     (%Location;)>
+<!ATTLIST large-icon     id             ID              #IMPLIED>
+
+
+<!-- The "small-icon" element specifies the location, relative to the Struts
+     configuration file, of a resource containing a small (16x16 pixel)
+     icon image.
+-->
+<!ELEMENT small-icon     (%Location;)>
+<!ATTLIST small-icon     id             ID              #IMPLIED>
diff --git a/Java-base/tiles/src/tiles-compat/src/main/resources/org/apache/tiles/compat/resources/tiles-config_1_4.dtd b/Java-base/tiles/src/tiles-compat/src/main/resources/org/apache/tiles/compat/resources/tiles-config_1_4.dtd
new file mode 100644
index 000000000..85abdfba8
--- /dev/null
+++ b/Java-base/tiles/src/tiles-compat/src/main/resources/org/apache/tiles/compat/resources/tiles-config_1_4.dtd
@@ -0,0 +1,299 @@
+<!--
+    $Id$
+
+    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.
+-->
+<!--
+     DTD for the Tile Definition File, Version 1.4
+
+     To support validation of your configuration file, include the following
+     DOCTYPE element at the beginning (after the "xml" declaration):
+
+     <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 1.4//EN"
+       "http://struts.apache.org/dtds/tiles-config_1_4.dtd">
+
+     $Id$
+-->
+
+
+<!-- ========== Defined Types ============================================= -->
+
+
+<!-- A "Boolean" is the string representation of a boolean (true or false)
+     variable.
+-->
+<!ENTITY % Boolean "(true|false)">
+
+
+<!-- A "ContentType" is the content type of an attribute passed to a tile
+     component.
+-->
+<!ENTITY % ContentType "(string|page|template|definition)">
+
+<!-- A "ClassName" is the fully qualified name of a Java class that is
+     instantiated to provide the functionality of the enclosing element.
+-->
+<!ENTITY % ClassName "CDATA">
+
+<!-- A "RequestPath" is an module-relative URI path, beginning with a
+     slash, that identifies a mapped resource (such as a JSP page or a servlet)
+     within this web application.
+-->
+<!ENTITY % RequestPath "CDATA">
+
+<!-- A "DefinitionName" is the unique identifier of a definition. This identifier
+     is a logical name used to reference the definition.
+-->
+<!ENTITY % DefinitionName "CDATA">
+
+<!-- A "BeanName" is the identifier of a JavaBean, such as a form bean,
+     and also serves as the name of the corresponding scripting variable
+     and the name of the JSP attribute under which the bean is accessed.
+     Therefore, it must conform to the rules for a Java identifier.
+-->
+<!ENTITY % BeanName "CDATA">
+
+<!-- A "PropName" is the name of a JavaBeans property, and must begin with
+     a lower case letter and contain only characters that are legal in a
+     Java identifier.
+-->
+<!ENTITY % PropName "CDATA">
+
+<!-- A "Location" is a relative path, delimited by "/" characters, that
+     defines the location of a resource relative to the location of the
+     configuration file itself.
+-->
+<!ENTITY % Location "#PCDATA">
+
+
+
+<!-- ========== Top Level Elements ======================================== -->
+
+
+  <!-- deprecated: use tiles-definitions instead.-->
+<!ELEMENT component-definitions (definition+)>
+
+<!-- The "tiles-definitions" element is the root of the configuration file
+     hierarchy, and contains nested elements for all of the other
+     configuration settings.
+-->
+<!ELEMENT tiles-definitions (definition+)>
+
+<!-- The "definition" element describes a definition that can be inserted in a jsp
+     page. This definition is identified by its logical name. A definition allows
+     to define all the attributes that can be set in <insert> tag from a jsp page.
+
+     controllerClass The fully qualified Java class name of the controller
+                     subclass to call immediately before the tiles is inserted.
+                     Only one of controllerClass or controllerUrl should be
+                     specified.
+
+     controllerUrl   The context-relative path to the resource used as controller
+                     called immediately before the tiles is inserted.
+                     Only one of controllerClass or controllerUrl should be
+                     specified.
+
+     extends         Name of a definition that is used as ancestor of this definition.
+                     All attributes from the ancestor are available to the new
+                     definition. Any attribute inherited from the ancestor can
+                     be overloaded by providing a new value.
+
+     name            The unique identifier for this definition.
+
+     page            Same as path.
+
+     path            The context-relative path to the resource used as tiles to
+                     insert. This tiles will be inserted and a tiles context
+                     containing appropriate attributes will be available.
+
+     role            Security role name that is allowed access to this definition
+                     object. The definition is inserted only if the role name is
+                     allowed.
+
+     template        Same as path. For compatibility with the template tag library.
+-->
+<!ELEMENT definition (icon?, display-name?, description?, put*, putList*)>
+<!ATTLIST definition       id               ID               #IMPLIED>
+<!ATTLIST definition       controllerClass  %ClassName;      #IMPLIED>
+<!ATTLIST definition       controllerUrl    %RequestPath;    #IMPLIED>
+<!ATTLIST definition       extends          %DefinitionName; #IMPLIED>
+<!ATTLIST definition       name             %DefinitionName; #REQUIRED>
+<!ATTLIST definition       page             %RequestPath;    #IMPLIED>
+<!ATTLIST definition       path             %RequestPath;    #IMPLIED>
+<!ATTLIST definition       role             CDATA            #IMPLIED>
+<!ATTLIST definition       template         %RequestPath;    #IMPLIED>
+
+
+<!-- The "put" element describes an attribute of a definition. It allows to
+     specify the tiles attribute name and its value. The tiles value can be
+     specified as an xml attribute, or in the body of the <put> tag.
+
+     content         Same as value. For compatibility with the template tag library.
+
+     direct          Same as type="string". For compatibility with the template
+                     tag library.
+
+     name            The unique identifier for this put.
+
+     type            The type of the value. Can be: string, page, template or definition.
+                     By default, no type is associated to a value. If a type is
+                     associated, it will be used as a hint to process the value
+                     when the attribute will be used in the inserted tiles.
+
+     value           The value associated to this tiles attribute. The value should
+                     be specified with this tag attribute, or in the body of the tag.
+-->
+<!ELEMENT put (#PCDATA)>
+<!ATTLIST put              id               ID              #IMPLIED>
+<!ATTLIST put              content          CDATA           #IMPLIED>
+<!ATTLIST put              direct           %Boolean;       #IMPLIED>
+<!ATTLIST put              name             CDATA           #REQUIRED>
+<!ATTLIST put              type             %ContentType;   #IMPLIED>
+<!ATTLIST put              value            CDATA           #IMPLIED>
+
+
+<!-- The "putList" element describes a list attribute of a definition. It allows to
+     specify an attribute that is a java List containing any kind of values. In
+     the config file, the list elements are specified by nested <add>, <item> or
+     <putList>.
+
+     name            The unique identifier for this put list.
+-->
+<!ELEMENT putList ( (add* | item* | bean* | putList*)+) >
+<!ATTLIST putList          id               ID              #IMPLIED>
+<!ATTLIST putList          name             CDATA           #REQUIRED>
+
+<!-- ========== Subordinate Elements ====================================== -->
+
+<!-- The "add" element describes an element of a list. It is similar to the
+     <put> element.
+
+     content         Same as value. For compatibility with the template tag library.
+
+     direct          Same as type="string". For compatibility with the template
+                     tag library.
+
+     type            The type of the value. Can be: string, page, template or definition.
+                     By default, no type is associated to a value. If a type is
+                     associated, it will be used as a hint to process the value
+                     when the attribute will be used in the inserted tiles.
+
+     value           The value associated to this tiles attribute. The value should
+                     be specified with this tag attribute, or in the body of the tag.
+-->
+<!ELEMENT add (#PCDATA)>
+<!ATTLIST add              id               ID              #IMPLIED>
+<!ATTLIST add              content          CDATA           #IMPLIED>
+<!ATTLIST add              direct           %Boolean;       #IMPLIED>
+<!ATTLIST add              type             %ContentType;   #IMPLIED>
+<!ATTLIST add              value            CDATA           #IMPLIED>
+
+
+<!-- The "bean" element describes an element of a list. It create a bean of the
+     specified java classtype. This bean is initialized with appropriate nested
+     <set-property>.
+
+     classtype       The fully qualified classname for this bean.
+-->
+<!ELEMENT bean (set-property*)>
+<!ATTLIST bean             id               ID              #IMPLIED>
+<!ATTLIST bean             classtype        %ClassName;     #REQUIRED>
+
+<!-- The "set-property" element specifies the method name and initial value of
+     a bean property. When the object representing
+     the surrounding element is instantiated, the accessor for the indicated
+     property is called and passed the indicated value.
+
+     property        Name of the JavaBeans property whose setter method
+                     will be called.
+
+     value           String representation of the value to which this
+                     property will be set, after suitable type conversion
+-->
+<!ELEMENT set-property   EMPTY>
+<!ATTLIST set-property   id             ID              #IMPLIED>
+<!ATTLIST set-property   property       %PropName;      #REQUIRED>
+<!ATTLIST set-property   value          CDATA           #REQUIRED>
+
+
+<!-- The "item" element describes an element of a list. It create a bean added as
+     element to the list. Each bean can contain different properties: value, link,
+     icon, tooltip. These properties are to be interpreted by the jsp page using
+     them.
+     By default the bean is of type
+     "org.apache.struts.tiles.beans.SimpleMenuItem". This bean is useful to
+     create a list of beans used as menu items.
+
+     classtype       The fully qualified classtype for this bean.
+                     If specified, the classtype must be a subclass of the interface
+                     "org.apache.struts.tiles.beans.MenuItem".
+
+     icon            The bean 'icon' property.
+
+     link            The bean 'link' property.
+
+     tooltip         The bean 'tooltip' property.
+
+     value           The bean 'value' property.
+-->
+<!ELEMENT item (#PCDATA)>
+<!ATTLIST item             id               ID              #IMPLIED>
+<!ATTLIST item             classtype        %ClassName;     #IMPLIED>
+<!ATTLIST item             icon             CDATA           #IMPLIED>
+<!ATTLIST item             link             CDATA           #REQUIRED>
+<!ATTLIST item             tooltip          CDATA           #IMPLIED>
+<!ATTLIST item             value            CDATA           #REQUIRED>
+
+
+<!-- ========== Info Elements ====================================== -->
+
+<!-- The "description" element contains descriptive (paragraph length) text
+     about the surrounding element, suitable for use in GUI tools.
+-->
+<!ELEMENT description    (#PCDATA)>
+<!ATTLIST description    id             ID              #IMPLIED>
+
+
+<!-- The "display-name" element contains a short (one line) description of
+     the surrounding element, suitable for use in GUI tools.
+-->
+<!ELEMENT display-name (#PCDATA)>
+<!ATTLIST display-name   id             ID              #IMPLIED>
+
+
+<!-- The "icon" element contains a small-icon and large-icon element which
+     specify the location, relative to the Struts configuration file, for small
+     and large images used to represent the surrounding element in GUI tools.
+-->
+<!ELEMENT icon           (small-icon?, large-icon?)>
+<!ATTLIST icon           id             ID              #IMPLIED>
+
+
+<!-- The "large-icon" element specifies the location, relative to the Struts
+     configuration file, of a resource containing a large (32x32 pixel)
+     icon image.
+-->
+<!ELEMENT large-icon     (%Location;)>
+<!ATTLIST large-icon     id             ID              #IMPLIED>
+
+
+<!-- The "small-icon" element specifies the location, relative to the Struts
+     configuration file, of a resource containing a small (16x16 pixel)
+     icon image.
+-->
+<!ELEMENT small-icon     (%Location;)>
+<!ATTLIST small-icon     id             ID              #IMPLIED>
diff --git a/Java-base/tiles/src/tiles-compat/src/main/resources/org/apache/tiles/compat/resources/tiles-config_2_0.dtd b/Java-base/tiles/src/tiles-compat/src/main/resources/org/apache/tiles/compat/resources/tiles-config_2_0.dtd
new file mode 100644
index 000000000..21140afa3
--- /dev/null
+++ b/Java-base/tiles/src/tiles-compat/src/main/resources/org/apache/tiles/compat/resources/tiles-config_2_0.dtd
@@ -0,0 +1,322 @@
+<!--
+%
+   $Id$
+
+   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.
+
+%
+
+@hidden $Id$
+@title DTD for the Tiles Definition File, Version 2.0
+@doctype tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN" "http://tiles.apache.org/dtds/tiles-config_2_0.dtd"
+@root tiles-definitions
+-->
+
+
+<!-- ========== Defined Types ============================================= -->
+
+
+<!-- A "Boolean" is the string representation of a boolean (true or false)
+     variable.
+-->
+<!ENTITY % Boolean "(true|false)">
+
+
+<!-- A "ContentType" is the content type of an attribute passed to a template.
+-->
+<!ENTITY % ContentType "(string|template|definition|object)">
+
+<!-- A "ClassName" is the fully qualified name of a Java class that is
+     instantiated to provide the functionality of the enclosing element.
+-->
+<!ENTITY % ClassName "CDATA">
+
+<!-- A "RequestPath" is an module-relative URI path, beginning with a
+     slash, that identifies a mapped resource (such as a JSP page or a servlet)
+     within this web application.
+-->
+<!ENTITY % RequestPath "CDATA">
+
+<!-- A "DefinitionName" is the unique identifier of a definition. This identifier
+     is a logical name used to reference the definition.
+-->
+<!ENTITY % DefinitionName "CDATA">
+
+<!-- A "BeanName" is the identifier of a JavaBean, such as a form bean,
+     and also serves as the name of the corresponding scripting variable
+     and the name of the JSP attribute under which the bean is accessed.
+     Therefore, it must conform to the rules for a Java identifier.
+-->
+<!ENTITY % BeanName "CDATA">
+
+<!-- A "PropName" is the name of a JavaBeans property, and must begin with
+     a lower case letter and contain only characters that are legal in a
+     Java identifier.
+-->
+<!ENTITY % PropName "CDATA">
+
+<!-- A "Location" is a relative path, delimited by "/" characters, that
+     defines the location of a resource relative to the location of the
+     configuration file itself.
+-->
+<!ENTITY % Location "#PCDATA">
+
+
+
+<!-- ========== Top Level Elements ======================================== -->
+
+
+<!-- The "tiles-definitions" element is the root of the configuration file
+     hierarchy, and contains nested elements for all of the other
+     configuration settings.
+-->
+<!ELEMENT tiles-definitions (definition+)>
+
+<!-- The "definition" element describes a definition that can be inserted in a jsp
+     page. This definition is identified by its logical name. A definition allows
+     to define all the attributes that can be set in <insert> tag from a jsp page.
+-->
+<!ELEMENT definition (icon?, display-name?, description?, put-attribute*, put-list-attribute*)>
+<!ATTLIST definition       id               ID               #IMPLIED>
+<!--
+@attr preparer       The fully qualified Java class name of the preparer
+                     subclass to call immediately before the tiles is inserted.
+                     Only one of preparerClass or preparerUrl should be
+                     specified.
+-->
+<!ATTLIST definition       preparer         %ClassName;      #IMPLIED>
+<!--
+@attr extends        Name of a definition that is used as ancestor of this definition.
+                     All attributes from the ancestor are available to the new
+                     definition. Any attribute inherited from the ancestor can
+                     be overloaded by providing a new value.
+-->
+<!ATTLIST definition       extends          %DefinitionName; #IMPLIED>
+<!--
+@attr name           The unique identifier for this definition.
+-->
+<!ATTLIST definition       name             %DefinitionName; #REQUIRED>
+<!--
+@attr role           Security role name that is allowed access to this definition
+                     object. The definition is inserted only if the role name is
+                     allowed.
+-->
+<!ATTLIST definition       role             CDATA            #IMPLIED>
+<!--
+@attr template       The context-relative path to the resource used as tiles to
+                     insert. This tiles will be inserted and a tiles context
+                     containing appropriate attributes will be available.
+-->
+<!ATTLIST definition       template         %RequestPath;    #IMPLIED>
+
+
+<!-- The "put-attribute" element describes an attribute of a definition. It allows to
+     specify the tiles attribute name and its value. The tiles value can be
+     specified as an xml attribute, or in the body of the <put-attribute> tag.
+-->
+<!ELEMENT put-attribute (#PCDATA)>
+<!ATTLIST put-attribute     id               ID              #IMPLIED>
+<!--
+@attr name           The unique identifier for this put-attribute.
+-->
+<!ATTLIST put-attribute     name             CDATA           #REQUIRED>
+<!--
+@attr type           The type of the value. Can be: string, template or definition.
+                     By default, no type is associated to a value. If a type is
+                     associated, it will be used as a hint to process the value
+                     when the attribute will be used in the inserted tiles.
+-->
+<!ATTLIST put-attribute     type             %ContentType;   #IMPLIED>
+<!--
+@attr value          The value associated to this tiles attribute. The value should
+                     be specified with this tag attribute, or in the body of the tag.
+-->
+<!ATTLIST put-attribute     value            CDATA           #IMPLIED>
+<!--
+@attr role           Security role name that is allowed access to this attribute
+                     object. The attribute is inserted only if the role name is
+                     allowed.
+-->
+<!ATTLIST put-attribute     role             CDATA            #IMPLIED>
+
+
+<!-- The "put-list-attribute" element describes a list attribute of a definition. It allows to
+     specify an attribute that is a java List containing any kind of values. In
+     the config file, the list elements are specified by nested <add-attribute>, <item> or
+     <add-list-attribute>.
+-->
+<!ELEMENT put-list-attribute ( (add-attribute* | item* | bean* | add-list-attribute*)+) >
+<!ATTLIST put-list-attribute id               ID              #IMPLIED>
+<!--
+@attr name           The unique identifier for this put attribute list.
+-->
+<!ATTLIST put-list-attribute name             CDATA           #REQUIRED>
+<!--
+@attr role           Security role name that is allowed access to this attribute
+                     object. The attribute is inserted only if the role name is
+                     allowed.
+-->
+<!ATTLIST put-list-attribute role             CDATA            #IMPLIED>
+
+<!-- ========== Subordinate Elements ====================================== -->
+
+
+<!-- The "add-attribute" element describes an element of a list. It is similar to the
+     <put> element.
+-->
+<!ELEMENT add-attribute (#PCDATA)>
+<!ATTLIST add-attribute              id               ID              #IMPLIED>
+<!--
+@attr type           The type of the value. Can be: string, template or definition.
+                     By default, no type is associated to a value. If a type is
+                     associated, it will be used as a hint to process the value
+                     when the attribute will be used in the inserted tiles.
+-->
+<!ATTLIST add-attribute              type             %ContentType;   #IMPLIED>
+<!--
+@attr value          The value associated to this tiles attribute. The value should
+                     be specified with this tag attribute, or in the body of the tag.
+-->
+<!ATTLIST add-attribute              value            CDATA           #IMPLIED>
+<!--
+@attr role           Security role name that is allowed access to this attribute
+                     object. The attribute will be added to the parent list
+                     anyway. It is delegated to the user of this attribute to
+                     use it or not depending on the role of the user.
+-->
+<!ATTLIST add-attribute              role             CDATA            #IMPLIED>
+
+<!-- The "add-list-attribute" element describes a list attribute subordinate to another
+     list attribute. It allows to specify an attribute value that is a java List
+     containing any kind of values. In the config file, the list elements are specified
+     by nested <add-attribute>, <item> or
+     <add-list-attribute>.
+-->
+<!ELEMENT add-list-attribute ( (add-attribute* | item* | bean* | add-list-attribute*)+) >
+<!ATTLIST add-list-attribute id               ID              #IMPLIED>
+<!--
+@attr role           Security role name that is allowed access to this attribute
+                     object. The attribute will be added to the parent list
+                     anyway. It is delegated to the user of this attribute to
+                     use it or not depending on the role of the user.
+-->
+<!ATTLIST add-list-attribute role             CDATA            #IMPLIED>
+
+
+<!-- The "bean" element describes an element of a list. It create a bean of the
+     specified java classtype. This bean is initialized with appropriate nested
+     <set-property>.
+-->
+<!ELEMENT bean (set-property*)>
+<!ATTLIST bean             id               ID              #IMPLIED>
+<!--
+@attr classtype      The fully qualified classname for this bean.
+-->
+<!ATTLIST bean             classtype        %ClassName;     #REQUIRED>
+
+<!-- The "set-property" element specifies the method name and initial value of
+     a bean property. When the object representing
+     the surrounding element is instantiated, the accessor for the indicated
+     property is called and passed the indicated value.
+-->
+<!ELEMENT set-property   EMPTY>
+<!ATTLIST set-property   id             ID              #IMPLIED>
+<!--
+@attr property       Name of the JavaBeans property whose setter method
+                     will be called.
+-->
+<!ATTLIST set-property   property       %PropName;      #REQUIRED>
+<!--
+@attr value          String representation of the value to which this
+                     property will be set, after suitable type conversion
+-->
+<!ATTLIST set-property   value          CDATA           #REQUIRED>
+
+
+<!-- The "item" element describes an element of a list. It create a bean added as
+     element to the list. Each bean can contain different properties: value, link,
+     icon, tooltip. These properties are to be interpreted by the jsp page using
+     them.
+     By default the bean is of type
+     "org.apache.struts.tiles.beans.SimpleMenuItem". This bean is useful to
+     create a list of beans used as menu items.
+-->
+<!ELEMENT item (#PCDATA)>
+<!ATTLIST item             id               ID              #IMPLIED>
+<!--
+@attr classtype      The fully qualified classtype for this bean.
+                     If specified, the classtype must be a subclass of the interface
+                     "org.apache.struts.tiles.beans.MenuItem".
+-->
+<!ATTLIST item             classtype        %ClassName;     #IMPLIED>
+<!--
+@attr icon           The bean 'icon' property.
+-->
+<!ATTLIST item             icon             CDATA           #IMPLIED>
+<!--
+@attr link           The bean 'link' property.
+-->
+<!ATTLIST item             link             CDATA           #REQUIRED>
+<!--
+@attr tooltip        The bean 'tooltip' property.
+-->
+<!ATTLIST item             tooltip          CDATA           #IMPLIED>
+<!--
+@attr value          The bean 'value' property.
+-->
+<!ATTLIST item             value            CDATA           #REQUIRED>
+
+
+<!-- ========== Info Elements ====================================== -->
+
+<!-- The "description" element contains descriptive (paragraph length) text
+     about the surrounding element, suitable for use in GUI tools.
+-->
+<!ELEMENT description    (#PCDATA)>
+<!ATTLIST description    id             ID              #IMPLIED>
+
+
+<!-- The "display-name" element contains a short (one line) description of
+     the surrounding element, suitable for use in GUI tools.
+-->
+<!ELEMENT display-name (#PCDATA)>
+<!ATTLIST display-name   id             ID              #IMPLIED>
+
+
+<!-- The "icon" element contains a small-icon and large-icon element which
+     specify the location, relative to the Struts configuration file, for small
+     and large images used to represent the surrounding element in GUI tools.
+-->
+<!ELEMENT icon           (small-icon?, large-icon?)>
+<!ATTLIST icon           id             ID              #IMPLIED>
+
+
+<!-- The "large-icon" element specifies the location, relative to the Struts
+     configuration file, of a resource containing a large (32x32 pixel)
+     icon image.
+-->
+<!ELEMENT large-icon     (%Location;)>
+<!ATTLIST large-icon     id             ID              #IMPLIED>
+
+
+<!-- The "small-icon" element specifies the location, relative to the Struts
+     configuration file, of a resource containing a small (16x16 pixel)
+     icon image.
+-->
+<!ELEMENT small-icon     (%Location;)>
+<!ATTLIST small-icon     id             ID              #IMPLIED>
diff --git a/Java-base/tiles/src/tiles-compat/src/main/resources/org/apache/tiles/compat/resources/tiles-config_2_1.dtd b/Java-base/tiles/src/tiles-compat/src/main/resources/org/apache/tiles/compat/resources/tiles-config_2_1.dtd
new file mode 100644
index 000000000..689b6e7c4
--- /dev/null
+++ b/Java-base/tiles/src/tiles-compat/src/main/resources/org/apache/tiles/compat/resources/tiles-config_2_1.dtd
@@ -0,0 +1,364 @@
+<!--
+%
+   $Id$
+
+   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.
+
+%
+
+@hidden $Id$
+@title DTD for the Tiles Definition File, Version 2.1
+@doctype tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration 2.1//EN" "http://tiles.apache.org/dtds/tiles-config_2_1.dtd"
+@root tiles-definitions
+-->
+
+
+<!-- ========== Defined Types ============================================= -->
+
+
+<!-- A "Boolean" is the string representation of a boolean (true or false)
+     variable.
+-->
+<!ENTITY % Boolean "(true|false)">
+
+
+<!-- A "ContentType" is the content type of an attribute passed to a template.
+-->
+<!ENTITY % ContentType "CDATA">
+
+<!-- A "ClassName" is the fully qualified name of a Java class that is
+     instantiated to provide the functionality of the enclosing element.
+-->
+<!ENTITY % ClassName "CDATA">
+
+<!-- A "RequestPath" is an module-relative URI path, beginning with a
+     slash, that identifies a mapped resource (such as a JSP page or a servlet)
+     within this web application.
+-->
+<!ENTITY % RequestPath "CDATA">
+
+<!-- A "DefinitionName" is the unique identifier of a definition. This identifier
+     is a logical name used to reference the definition.
+-->
+<!ENTITY % DefinitionName "CDATA">
+
+<!-- A "BeanName" is the identifier of a JavaBean, such as a form bean,
+     and also serves as the name of the corresponding scripting variable
+     and the name of the JSP attribute under which the bean is accessed.
+     Therefore, it must conform to the rules for a Java identifier.
+-->
+<!ENTITY % BeanName "CDATA">
+
+<!-- A "PropName" is the name of a JavaBeans property, and must begin with
+     a lower case letter and contain only characters that are legal in a
+     Java identifier.
+-->
+<!ENTITY % PropName "CDATA">
+
+<!-- A "Location" is a relative path, delimited by "/" characters, that
+     defines the location of a resource relative to the location of the
+     configuration file itself.
+-->
+<!ENTITY % Location "#PCDATA">
+
+
+
+<!-- ========== Top Level Elements ======================================== -->
+
+
+<!-- The "tiles-definitions" element is the root of the configuration file
+     hierarchy, and contains nested elements for all of the other
+     configuration settings.
+-->
+<!ELEMENT tiles-definitions (definition+)>
+
+<!-- The "definition" element describes a definition that can be inserted in a jsp
+     page. This definition is identified by its logical name. A definition allows
+     to define all the attributes that can be set in <insert> tag from a jsp page.
+-->
+<!ELEMENT definition (icon?, display-name?, description?, put-attribute*, put-list-attribute*)>
+<!ATTLIST definition       id               ID               #IMPLIED>
+<!--
+@attr preparer       The fully qualified Java class name of the preparer
+                     subclass to call immediately before the tiles is inserted.
+                     Only one of preparerClass or preparerUrl should be
+                     specified.
+-->
+<!ATTLIST definition       preparer         %ClassName;      #IMPLIED>
+<!--
+@attr extends        Name of a definition that is used as ancestor of this definition.
+                     All attributes from the ancestor are available to the new
+                     definition. Any attribute inherited from the ancestor can
+                     be overloaded by providing a new value.
+-->
+<!ATTLIST definition       extends          %DefinitionName; #IMPLIED>
+<!--
+@attr name           The unique identifier for this definition. Required when
+                     it is a root definition, while it is implied in nested
+                     definitions.
+-->
+<!ATTLIST definition       name             %DefinitionName; #IMPLIED>
+<!--
+@attr role           Security role name that is allowed access to this definition
+                     object. The definition is inserted only if the role name is
+                     allowed.
+-->
+<!ATTLIST definition       role             CDATA            #IMPLIED>
+<!--
+@attr template       The context-relative path to the resource used as tiles to
+                     insert. This tiles will be inserted and a tiles context
+                     containing appropriate attributes will be available.
+-->
+<!ATTLIST definition       template         %RequestPath;    #IMPLIED>
+<!--
+@attr templateExpression The expression that will evaluate to a template for this definition.
+               This attribute will be ignored if template is specified.
+
+-->
+<!ATTLIST definition       templateExpression       CDATA    #IMPLIED>
+<!--
+@attr templateType   The type of the template attribute. Can be: string,
+           template or definition.
+                     By default, the type is "template". If a type is
+                     associated, the desidered renderer will be invoked.
+-->
+<!ATTLIST definition       templateType             %ContentType;   #IMPLIED>
+
+<!-- The "put-attribute" element describes an attribute of a definition. It allows to
+     specify the tiles attribute name and its value. The tiles value can be
+     specified as an xml attribute, or in the body of the <put-attribute> tag.
+-->
+<!ELEMENT put-attribute ( (definition*) )>
+<!ATTLIST put-attribute     id               ID              #IMPLIED>
+<!--
+@attr name           The unique identifier for this put-attribute.
+-->
+<!ATTLIST put-attribute     name             CDATA           #REQUIRED>
+<!--
+@attr type           The type of the value. Can be: string, template or definition.
+                     By default, no type is associated to a value. If a type is
+                     associated, it will be used as a hint to process the value
+                     when the attribute will be used in the inserted tiles.
+-->
+<!ATTLIST put-attribute     type             %ContentType;   #IMPLIED>
+<!--
+@attr value          The value associated to this tiles attribute. The value should
+                     be specified with this tag attribute, or in the body of the tag.
+-->
+<!ATTLIST put-attribute     value            CDATA           #IMPLIED>
+<!--
+@attr expression     The expression associated to this tiles attribute. This
+           attribute will be ignored if value is specified.
+
+-->
+<!ATTLIST put-attribute     expression       CDATA           #IMPLIED>
+<!--
+@attr role           Security role name that is allowed access to this attribute
+                     object. The attribute is inserted only if the role name is
+                     allowed.
+-->
+<!ATTLIST put-attribute     role             CDATA            #IMPLIED>
+<!--
+@attr cascade        If true, the attribute will be cascaded to all inner
+                     definitions. By default, cascade is false.
+-->
+<!ATTLIST put-attribute     cascade          %Boolean;    #IMPLIED>
+
+
+<!-- The "put-list-attribute" element describes a list attribute of a definition. It allows to
+     specify an attribute that is a java List containing any kind of values. In
+     the config file, the list elements are specified by nested <add-attribute>, <item> or
+     <add-list-attribute>.
+-->
+<!ELEMENT put-list-attribute ( (add-attribute* | item* | bean* | add-list-attribute*)+) >
+<!ATTLIST put-list-attribute id               ID              #IMPLIED>
+<!--
+@attr name           The unique identifier for this put attribute list.
+-->
+<!ATTLIST put-list-attribute name             CDATA           #REQUIRED>
+<!--
+@attr role           Security role name that is allowed access to this attribute
+                     object. The attribute is inserted only if the role name is
+                     allowed.
+-->
+<!ATTLIST put-list-attribute role             CDATA            #IMPLIED>
+<!--
+@attr inherit        If true, the attribute will put the elements of the attribute
+                     with the same name of the parent definition before the ones
+                     specified here. By default, it is 'false'.
+-->
+<!ATTLIST put-list-attribute inherit          %Boolean;        #IMPLIED>
+<!--
+@attr cascade        If true, the attribute will be cascaded to all inner
+                     definitions. By default, cascade is false.
+-->
+<!ATTLIST put-list-attribute cascade          %Boolean;        #IMPLIED>
+
+<!-- ========== Subordinate Elements ====================================== -->
+
+
+<!-- The "add-attribute" element describes an element of a list. It is similar to the
+     <put> element.
+-->
+<!ELEMENT add-attribute ( (definition*) )>
+<!ATTLIST add-attribute              id               ID              #IMPLIED>
+<!--
+@attr type           The type of the value. Can be: string, template or definition.
+                     By default, no type is associated to a value. If a type is
+                     associated, it will be used as a hint to process the value
+                     when the attribute will be used in the inserted tiles.
+-->
+<!ATTLIST add-attribute              type             %ContentType;   #IMPLIED>
+<!--
+@attr value          The value associated to this tiles attribute. The value should
+                     be specified with this tag attribute, or in the body of the tag.
+-->
+<!ATTLIST add-attribute              value            CDATA           #IMPLIED>
+<!--
+@attr expression     The expression associated to this tiles attribute. This
+           attribute will be ignored if value is specified.
+
+-->
+<!ATTLIST add-attribute              expression       CDATA           #IMPLIED>
+<!--
+@attr role           Security role name that is allowed access to this attribute
+                     object. The attribute will be added to the parent list
+                     anyway. It is delegated to the user of this attribute to
+                     use it or not depending on the role of the user.
+-->
+<!ATTLIST add-attribute              role             CDATA            #IMPLIED>
+
+<!-- The "add-list-attribute" element describes a list attribute subordinate to another
+     list attribute. It allows to specify an attribute value that is a java List
+     containing any kind of values. In the config file, the list elements are specified
+     by nested <add-attribute>, <item> or
+     <add-list-attribute>.
+-->
+<!ELEMENT add-list-attribute ( (add-attribute* | item* | bean* | add-list-attribute*)+) >
+<!ATTLIST add-list-attribute id               ID              #IMPLIED>
+<!--
+@attr role           Security role name that is allowed access to this attribute
+                     object. The attribute will be added to the parent list
+                     anyway. It is delegated to the user of this attribute to
+                     use it or not depending on the role of the user.
+-->
+<!ATTLIST add-list-attribute role             CDATA            #IMPLIED>
+
+
+<!-- The "bean" element describes an element of a list. It create a bean of the
+     specified java classtype. This bean is initialized with appropriate nested
+     <set-property>.
+-->
+<!ELEMENT bean (set-property*)>
+<!ATTLIST bean             id               ID              #IMPLIED>
+<!--
+@attr classtype      The fully qualified classname for this bean.
+-->
+<!ATTLIST bean             classtype        %ClassName;     #REQUIRED>
+
+<!-- The "set-property" element specifies the method name and initial value of
+     a bean property. When the object representing
+     the surrounding element is instantiated, the accessor for the indicated
+     property is called and passed the indicated value.
+-->
+<!ELEMENT set-property   EMPTY>
+<!ATTLIST set-property   id             ID              #IMPLIED>
+<!--
+@attr property       Name of the JavaBeans property whose setter method
+                     will be called.
+-->
+<!ATTLIST set-property   property       %PropName;      #REQUIRED>
+<!--
+@attr value          String representation of the value to which this
+                     property will be set, after suitable type conversion
+-->
+<!ATTLIST set-property   value          CDATA           #REQUIRED>
+
+
+<!-- The "item" element describes an element of a list. It create a bean added as
+     element to the list. Each bean can contain different properties: value, link,
+     icon, tooltip. These properties are to be interpreted by the jsp page using
+     them.
+     By default the bean is of type
+     "org.apache.struts.tiles.beans.SimpleMenuItem". This bean is useful to
+     create a list of beans used as menu items.
+-->
+<!ELEMENT item (#PCDATA)>
+<!ATTLIST item             id               ID              #IMPLIED>
+<!--
+@attr classtype      The fully qualified classtype for this bean.
+                     If specified, the classtype must be a subclass of the interface
+                     "org.apache.struts.tiles.beans.MenuItem".
+-->
+<!ATTLIST item             classtype        %ClassName;     #IMPLIED>
+<!--
+@attr icon           The bean 'icon' property.
+-->
+<!ATTLIST item             icon             CDATA           #IMPLIED>
+<!--
+@attr link           The bean 'link' property.
+-->
+<!ATTLIST item             link             CDATA           #REQUIRED>
+<!--
+@attr tooltip        The bean 'tooltip' property.
+-->
+<!ATTLIST item             tooltip          CDATA           #IMPLIED>
+<!--
+@attr value          The bean 'value' property.
+-->
+<!ATTLIST item             value            CDATA           #REQUIRED>
+
+
+<!-- ========== Info Elements ====================================== -->
+
+<!-- The "description" element contains descriptive (paragraph length) text
+     about the surrounding element, suitable for use in GUI tools.
+-->
+<!ELEMENT description    (#PCDATA)>
+<!ATTLIST description    id             ID              #IMPLIED>
+
+
+<!-- The "display-name" element contains a short (one line) description of
+     the surrounding element, suitable for use in GUI tools.
+-->
+<!ELEMENT display-name (#PCDATA)>
+<!ATTLIST display-name   id             ID              #IMPLIED>
+
+
+<!-- The "icon" element contains a small-icon and large-icon element which
+     specify the location, relative to the Struts configuration file, for small
+     and large images used to represent the surrounding element in GUI tools.
+-->
+<!ELEMENT icon           (small-icon?, large-icon?)>
+<!ATTLIST icon           id             ID              #IMPLIED>
+
+
+<!-- The "large-icon" element specifies the location, relative to the Struts
+     configuration file, of a resource containing a large (32x32 pixel)
+     icon image.
+-->
+<!ELEMENT large-icon     (%Location;)>
+<!ATTLIST large-icon     id             ID              #IMPLIED>
+
+
+<!-- The "small-icon" element specifies the location, relative to the Struts
+     configuration file, of a resource containing a small (16x16 pixel)
+     icon image.
+-->
+<!ELEMENT small-icon     (%Location;)>
+<!ATTLIST small-icon     id             ID              #IMPLIED>
diff --git a/Java-base/tiles/src/tiles-compat/src/site/site.xml b/Java-base/tiles/src/tiles-compat/src/site/site.xml
new file mode 100644
index 000000000..7c9841a74
--- /dev/null
+++ b/Java-base/tiles/src/tiles-compat/src/site/site.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<project name="Apache Tiles - Compatibility Library">
+     <skin>
+        <groupId>org.apache.maven.skins</groupId>
+        <artifactId>maven-fluido-skin</artifactId>
+        <version>1.3.0</version>
+     </skin>
+     <custom>
+        <fluidoSkin>
+        <topBarEnabled>true</topBarEnabled>
+        <sideBarEnabled>false</sideBarEnabled>
+        <searchEnabled>true</searchEnabled>
+        <gitHub>
+            <projectId>apache/tiles</projectId>
+            <ribbonOrientation>right</ribbonOrientation>
+            <ribbonColor>darkblue</ribbonColor>
+        </gitHub>
+        </fluidoSkin>
+     </custom>
+    <bannerLeft>
+        <name>Apache Tiles&#8482;</name>
+        <src>http://tiles.apache.org/images/logo.png</src>
+        <href>http://tiles.apache.org</href>
+    </bannerLeft>
+    <bannerRight>
+        <name>Apache Software Foundation</name>
+        <src>http://struts.apache.org/images/asf-logo.gif</src>
+        <href>http://www.apache.org</href>
+    </bannerRight>
+    <body>
+
+        <menu name="Apache Tiles&#8482;">
+            <item
+                   name="Welcome"
+                   href="../../index.html"/>
+            <item
+                    name="Tiles 3.0.x"
+                    href="../../framework/index.html"/>
+            <item
+                    name="Autotag 1.0.x"
+                    href="../../tiles-autotag/index.html"/>
+            <item
+                    name="Request 1.0.x"
+                    href="../../tiles-request/index.html"/>
+            <item
+                   name="Security bulletins"
+                   href="../security/index.html"/>
+            <item
+                   name="Download"
+                   href="http://tiles.apache.org/download.html"/>
+        </menu>
+
+        <menu ref="modules" />
+        <menu ref="reports" />
+
+        <footer>
+            <div class="row span12">
+                Apache Tiles, Tiles, Apache, the Apache feather logo, and the Apache Tiles
+                project logos are trademarks of The Apache Software Foundation.
+            </div>
+        </footer>
+    </body>
+</project>
diff --git a/Java-base/tiles/src/tiles-compat/src/test/java/org/apache/tiles/beans/SimpleMenuItemTest.java b/Java-base/tiles/src/tiles-compat/src/test/java/org/apache/tiles/beans/SimpleMenuItemTest.java
new file mode 100644
index 000000000..fd4b6c525
--- /dev/null
+++ b/Java-base/tiles/src/tiles-compat/src/test/java/org/apache/tiles/beans/SimpleMenuItemTest.java
@@ -0,0 +1,98 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.beans;
+
+import static org.junit.Assert.*;
+
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests {@link SimpleMenuItem}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class SimpleMenuItemTest {
+
+    /**
+     * The item to test.
+     */
+    private SimpleMenuItem item;
+
+    /**
+     * Sets up the test.
+     */
+    @Before
+    public void setUp() {
+        item = new SimpleMenuItem();
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.beans.SimpleMenuItem#setValue(java.lang.String)}.
+     */
+    @Test
+    public void testSetValue() {
+        item.setValue("value");
+        assertEquals("value", item.getValue());
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.beans.SimpleMenuItem#setLink(java.lang.String)}.
+     */
+    @Test
+    public void testSetLink() {
+        item.setLink("value");
+        assertEquals("value", item.getLink());
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.beans.SimpleMenuItem#setIcon(java.lang.String)}.
+     */
+    @Test
+    public void testSetIcon() {
+        item.setIcon("value");
+        assertEquals("value", item.getIcon());
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.beans.SimpleMenuItem#setTooltip(java.lang.String)}.
+     */
+    @Test
+    public void testSetTooltip() {
+        item.setTooltip("value");
+        assertEquals("value", item.getTooltip());
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.beans.SimpleMenuItem#toString()}.
+     */
+    @Test
+    public void testToString() {
+        item.setIcon("icon");
+        item.setLink("link");
+        item.setTooltip("tooltip");
+        item.setValue("value");
+        assertEquals(
+                "SimpleMenuItem[value=value, link=link, tooltip=tooltip, icon=icon, ]",
+                item.toString());
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-compat/src/test/java/org/apache/tiles/compat/definition/digester/TestCompatibilityDigesterDefinitionsReader.java b/Java-base/tiles/src/tiles-compat/src/test/java/org/apache/tiles/compat/definition/digester/TestCompatibilityDigesterDefinitionsReader.java
new file mode 100644
index 000000000..958a8948d
--- /dev/null
+++ b/Java-base/tiles/src/tiles-compat/src/test/java/org/apache/tiles/compat/definition/digester/TestCompatibilityDigesterDefinitionsReader.java
@@ -0,0 +1,176 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.compat.definition.digester;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Map;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.Definition;
+import org.apache.tiles.definition.DefinitionsFactoryException;
+import org.apache.tiles.definition.DefinitionsReader;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Tests the <code>org.apache.tiles.definition.digester.DigesterDefinitionsReader</code> class.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TestCompatibilityDigesterDefinitionsReader extends TestCase {
+
+    /**
+     * The logging object.
+     */
+    private final Logger log = LoggerFactory
+            .getLogger(TestCompatibilityDigesterDefinitionsReader.class);
+
+    /**
+     * The definitions reader.
+     */
+    private DefinitionsReader reader;
+
+    /**
+     * Creates a new instance of TestDigesterDefinitionsReader.
+     *
+     * @param name The name of the test.
+     */
+    public TestCompatibilityDigesterDefinitionsReader(String name) {
+        super(name);
+    }
+
+    /**
+     * @return a test suite (<code>TestSuite</code>) that includes all methods
+     *         starting with "test"
+     */
+    public static Test suite() {
+        return new TestSuite(TestCompatibilityDigesterDefinitionsReader.class);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        reader = new CompatibilityDigesterDefinitionsReader();
+    }
+
+    /**
+     * Tests the read method to read Tiles 1.1 files.
+     *
+     * @throws DefinitionsFactoryException If the definitions factory fails.
+     * @throws IOException If an I/O exception happens.
+     */
+    public void testReadOldFormat() throws IOException {
+        URL configFile = this.getClass().getClassLoader().getResource(
+                "org/apache/tiles/config/tiles-defs-1.1.xml");
+        assertNotNull("Config file not found", configFile);
+
+        InputStream source = configFile.openStream();
+        Map<String, Definition> definitions = reader.read(source);
+
+        assertNotNull("Definitions not returned.", definitions);
+        assertNotNull("Couldn't find doc.mainLayout tile.",
+                definitions.get("doc.mainLayout"));
+        assertNotNull("Couldn't Find title attribute.", definitions.get(
+                "doc.mainLayout").getAttribute("title").getValue());
+        assertEquals("Incorrect Find title attribute.",
+                "Tiles Library Documentation", definitions.get(
+                        "doc.mainLayout").getAttribute("title").getValue());
+    }
+
+    /**
+     * Tests the read method to read Tiles 2.0 files.
+     *
+     * @throws IOException If an I/O exception happens.
+     */
+    public void testReadNewFormat() throws IOException {
+        URL configFile = this.getClass().getClassLoader().getResource(
+                "org/apache/tiles/config/tiles-defs-2.0.xml");
+        assertNotNull("Config file not found", configFile);
+
+        InputStream source = configFile.openStream();
+        Map<String, Definition> definitions = reader.read(source);
+
+        assertNotNull("Definitions not returned.", definitions);
+        assertNotNull("Couldn't find doc.mainLayout tile.",
+                definitions.get("doc.mainLayout"));
+        assertNotNull("Couldn't Find title attribute.", definitions.get(
+                "doc.mainLayout").getAttribute("title").getValue());
+        assertEquals("Incorrect Find title attribute.",
+                "Tiles Library Documentation", definitions.get(
+                        "doc.mainLayout").getAttribute("title").getValue());
+    }
+
+    /**
+     * Tests the read method under normal conditions for the new features in 2.1
+     * version of the DTD.
+     */
+    public void testRead21Version() {
+        try {
+            URL configFile = this.getClass().getClassLoader().getResource(
+                    "org/apache/tiles/config/tiles-defs-2.1.xml");
+            assertNotNull("Config file not found", configFile);
+
+            InputStream source = configFile.openStream();
+            Map<String, Definition> definitions = reader.read(source);
+
+            assertNotNull("Definitions not returned.", definitions);
+            Definition def = definitions.get("doc.cascaded.test");
+
+            assertNotNull("Couldn't find doc.role.test tile.", def);
+            Attribute attribute = def.getLocalAttribute("title");
+            assertNotNull("Couldn't Find title local attribute.", attribute);
+            attribute = def.getCascadedAttribute("title2");
+            assertNotNull("Couldn't Find title2 cascaded attribute.", attribute);
+            attribute = def.getLocalAttribute("items1");
+            assertNotNull("Couldn't Find items1 local attribute.", attribute);
+            attribute = def.getCascadedAttribute("items2");
+            assertNotNull("Couldn't Find items2 cascaded attribute.", attribute);
+        } catch (Exception e) {
+            fail("Exception reading configuration." + e);
+        }
+    }
+
+    /**
+     * Tests read with bad input source.
+     */
+    public void testBadSource() {
+        try {
+            // Read definitions.
+            reader.read(new String("Bad Input"));
+            fail("Should've thrown an exception.");
+        } catch (DefinitionsFactoryException e) {
+            // correct.
+            if (log.isDebugEnabled()) {
+                log.debug("Exception caught, it is OK", e);
+            }
+        } catch (Exception e) {
+            fail("Exception reading configuration." + e);
+        }
+    }
+}
diff --git a/Java-base/tiles/src/tiles-compat/src/test/java/org/apache/tiles/compat/preparer/CompatibilityPreparerFactoryTest.java b/Java-base/tiles/src/tiles-compat/src/test/java/org/apache/tiles/compat/preparer/CompatibilityPreparerFactoryTest.java
new file mode 100644
index 000000000..03265d1e2
--- /dev/null
+++ b/Java-base/tiles/src/tiles-compat/src/test/java/org/apache/tiles/compat/preparer/CompatibilityPreparerFactoryTest.java
@@ -0,0 +1,72 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.compat.preparer;
+
+import junit.framework.TestCase;
+
+import org.apache.tiles.AttributeContext;
+import org.apache.tiles.preparer.ViewPreparer;
+import org.apache.tiles.request.Request;
+
+/**
+ * Tests {@link CompatibilityPreparerFactory}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class CompatibilityPreparerFactoryTest extends TestCase {
+
+    /**
+     * The factory to test.
+     */
+    private CompatibilityPreparerFactory factory;
+
+    /** {@inheritDoc} */
+    @Override
+    protected void setUp() {
+        factory = new CompatibilityPreparerFactory();
+    }
+
+    /**
+     * Test method for
+     * {@link org.apache.tiles.compat.preparer.CompatibilityPreparerFactory#createPreparer(java.lang.String)}
+     * .
+     */
+    public void testCreatePreparer() {
+        ViewPreparer preparer = factory.createPreparer("/my/url.do");
+        assertTrue("The preparer is not an UrlPreparer",
+                preparer instanceof UrlPreparer);
+        preparer = factory.createPreparer(MockViewPreparer.class.getName());
+        assertTrue("The preparer is not an class ViewPreparer",
+                preparer instanceof MockViewPreparer);
+    }
+
+    /**
+     * Mock view preparer to test preparer instantiation.
+     */
+    public static final class MockViewPreparer implements ViewPreparer {
+        /** {@inheritDoc} */
+        public void execute(Request tilesContext,
+                AttributeContext attributeContext) {
+            // Nothing here.
+        }
+    }
+}
diff --git a/Java-base/tiles/src/tiles-compat/src/test/java/org/apache/tiles/compat/preparer/UrlPreparerTest.java b/Java-base/tiles/src/tiles-compat/src/test/java/org/apache/tiles/compat/preparer/UrlPreparerTest.java
new file mode 100644
index 000000000..2c8e8bbd6
--- /dev/null
+++ b/Java-base/tiles/src/tiles-compat/src/test/java/org/apache/tiles/compat/preparer/UrlPreparerTest.java
@@ -0,0 +1,92 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.compat.preparer;
+
+import static org.easymock.EasyMock.*;
+
+import java.io.IOException;
+
+import org.apache.tiles.AttributeContext;
+import org.apache.tiles.preparer.PreparerException;
+import org.apache.tiles.request.DispatchRequest;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests {@link UrlPreparer}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class UrlPreparerTest {
+
+    /**
+     * The preparer to test.
+     */
+    private UrlPreparer preparer;
+
+    /**
+     * Sets up the test.
+     */
+    @Before
+    public void setUp() {
+        preparer = new UrlPreparer("/my/url.do");
+    }
+
+    /**
+     * Test method for
+     * {@link org.apache.tiles.compat.preparer.UrlPreparer#execute(
+     * org.apache.tiles.request.Request, org.apache.tiles.AttributeContext)}.
+     * @throws IOException If something goes wrong.
+     */
+    @Test
+    public void testExecute() throws IOException {
+        DispatchRequest requestContext = createMock(DispatchRequest.class);
+        AttributeContext attributeContext = createMock(AttributeContext.class);
+
+        requestContext.include("/my/url.do");
+        replay(requestContext, attributeContext);
+        preparer.execute(requestContext, attributeContext);
+        verify(requestContext, attributeContext);
+    }
+
+    /**
+     * Test method for
+     * {@link org.apache.tiles.compat.preparer.UrlPreparer#execute(
+     * org.apache.tiles.request.Request, org.apache.tiles.AttributeContext)}.
+     * @throws IOException If something goes wrong.
+     */
+    @Test(expected = PreparerException.class)
+    public void testExecuteException() throws IOException {
+        DispatchRequest requestContext = createMock(DispatchRequest.class);
+        AttributeContext attributeContext = createMock(AttributeContext.class);
+
+        requestContext.include("/my/url.do");
+        expectLastCall().andThrow(new IOException());
+
+        replay(requestContext, attributeContext);
+        try {
+            preparer.execute(requestContext, attributeContext);
+        } finally {
+            verify(requestContext, attributeContext);
+        }
+    }
+}
diff --git a/Java-base/tiles/src/tiles-compat/src/test/resources/org/apache/tiles/config/tiles-defs-1.1.xml b/Java-base/tiles/src/tiles-compat/src/test/resources/org/apache/tiles/config/tiles-defs-1.1.xml
new file mode 100644
index 000000000..96a049971
--- /dev/null
+++ b/Java-base/tiles/src/tiles-compat/src/test/resources/org/apache/tiles/config/tiles-defs-1.1.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 1.1//EN"
+       "http://struts.apache.org/dtds/tiles-config_1_1.dtd">
+
+<!-- Definitions for Tiles documentation   -->
+
+<tiles-definitions>
+
+  <!-- =======================================================  -->
+  <!-- Master definition  									-->
+  <!-- =======================================================  -->
+
+  <!-- Doc index page description  -->
+  <definition name="doc.mainLayout" template="/layout/classicLayout.jsp">
+    <put name="title"  value="Tiles Library Documentation" />
+    <put name="header" value="/common/header.jsp" />
+    <put name="menu"   value="doc.menu.main" />
+    <put name="footer" value="/common/footer.jsp" />
+    <put name="body"   value="doc.portal.body" />
+      <put name="bean"   value="This is an object" type="string" />
+  </definition>
+
+  <!-- =======================================================  -->
+  <!-- Main page body definitions  									-->
+  <!-- =======================================================  -->
+
+  <definition name="doc.portal.body" template="/layout/columnsLayout.jsp">
+    <put name="numCols" value="2" />
+    <putList name="list0" >
+      <add value="/doc/portal/welcome.jsp" />
+      <add value="/doc/portal/features.jsp" />
+      <!--<add value="/doc/portal/todo.jsp" /> -->
+      <add value="/doc/portal/documentation.jsp" />
+    </putList>
+    <putList name="list1" >
+      <add value="/doc/portal/news.jsp" />
+      <add value="/doc/portal/download.jsp" />
+      <add value="/doc/portal/tilesCompsTemplates.jsp" />
+      <add value="/doc/portal/strutsIntegration.jsp" />
+      <add value="/doc/portal/comments.jsp" />
+      <add value="/doc/portal/revisions.jsp" />
+    </putList>
+  </definition>
+
+  <!-- =======================================================  -->
+  <!-- Menus definitions  									-->
+  <!-- =======================================================  -->
+
+  <!-- Menu bar definition -->
+<definition name="doc.menu.main" template="/layout/vboxLayout.jsp" >
+  <putList name="componentsList" >
+    <add value="doc.menu.links" />
+    <add value="doc.menu.taglib.references" />
+    <add value="doc.menu.printer.friendly" />
+    <add value="doc.menu.old.documents" />
+  </putList>
+</definition>
+
+  <!-- Documentation menu definition v1.1-->
+<definition name="doc.menu.links" template="/layouts/menu.jsp" >
+  <put name="title" value="Documentation" />
+    <putList name="items" >
+      <item value="Home"           link="/index.jsp"  />
+      <item value="Live Examples (new)" link="/examples/index.jsp"  />
+      <!--
+    <item> <value>Commented Examples</value>
+        <link>/examples/index.jsp</link>
+      <classtype>org.apache.tiles.beans.SimpleMenuItem</classtype>
+    </item>
+    -->
+      <item value="Quick overview" link="/doc/quickOverview.jsp"  />
+      <!--
+      <item value="Tutorial"       link="/doc/tutorial.jsp"  />
+      -->
+      <item value="Tutorial Live Examples" link="/tutorial/index.jsp" />
+      <item value="Download"       link="/doc/download.jsp" />
+      <item value="Installation"   link="/doc/installation.jsp" />
+      <item value="User Guide"	   link="/doc/userGuide.jsp" />
+      <item value="Javadoc"        link="/api/index.html" />
+      <item value="Struts Home"    link="http://www.apache.org"   icon="/images/struts-power.gif"
+      classtype="org.apache.tiles.beans.SimpleMenuItem" />
+    </putList>
+</definition>
+
+  <!-- Printer friendly menu definition -->
+<definition name="doc.menu.printer.friendly" template="/layouts/menu.jsp" >
+  <put name="title" value="Printer Versions" />
+  <putList name="items" >
+    <item value="Quick Overview"     link="/test/testAll.jsp" />
+    <item value="Tutorial"           link="/doc/tutorialBody.html" />
+    <item value="User Guide"         link="/doc/userGuideBody.html" />
+    <item value="Overview (old)"  	 link="/doc/overviewBody.html" />
+  </putList>
+</definition>
+
+  <!-- Taglib menu definition -->
+<definition name="doc.menu.taglib.references" template="/layouts/menu.jsp" >
+  <put name="title" value="Tag Library Reference" />
+    <putList name="items" >
+      <item value="Tiles Tags"     link="/doc/tilesTags.jsp" />
+      <!-- <item value="Extension Tags (old)"   link="/doc/extensionsTags.jsp" /> -->
+    </putList>
+</definition>
+
+  <!-- Oldies menu definition -->
+<definition name="doc.menu.old.documents" template="/layouts/menu.jsp" >
+  <put name="title" value="Old Documents" />
+  <putList name="items" >
+    <item value="Overview (old)"     link="/doc/overview.jsp" />
+  </putList>
+</definition>
+
+
+</tiles-definitions>
diff --git a/Java-base/tiles/src/tiles-compat/src/test/resources/org/apache/tiles/config/tiles-defs-2.0.xml b/Java-base/tiles/src/tiles-compat/src/test/resources/org/apache/tiles/config/tiles-defs-2.0.xml
new file mode 100644
index 000000000..b03def5b7
--- /dev/null
+++ b/Java-base/tiles/src/tiles-compat/src/test/resources/org/apache/tiles/config/tiles-defs-2.0.xml
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
+       "http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
+
+<!-- Definitions for Tiles documentation   -->
+
+<tiles-definitions>
+
+  <!-- =======================================================  -->
+  <!-- Master definition  									-->
+  <!-- =======================================================  -->
+
+  <!-- Doc index page description  -->
+  <definition name="doc.mainLayout" template="/layout/classicLayout.jsp">
+    <put-attribute name="title"  value="Tiles Library Documentation" />
+    <put-attribute name="header" value="/common/header.jsp" />
+    <put-attribute name="menu"   value="doc.menu.main" />
+    <put-attribute name="footer" value="/common/footer.jsp" />
+    <put-attribute name="body"   value="doc.portal.body" />
+      <put-attribute name="bean"   value="This is an object" type="object" />
+  </definition>
+
+  <!-- =======================================================  -->
+  <!-- Main page body definitions  									-->
+  <!-- =======================================================  -->
+
+  <definition name="doc.portal.body" template="/layout/columnsLayout.jsp">
+    <put-attribute name="numCols" value="2" />
+    <put-list-attribute name="list0" >
+      <add-attribute value="/doc/portal/welcome.jsp" />
+      <add-attribute value="/doc/portal/features.jsp" />
+      <!--<add-attribute value="/doc/portal/todo.jsp" /> -->
+      <add-attribute value="/doc/portal/documentation.jsp" />
+    </put-list-attribute>
+    <put-list-attribute name="list1" >
+      <add-attribute value="/doc/portal/news.jsp" />
+      <add-attribute value="/doc/portal/download.jsp" />
+      <add-attribute value="/doc/portal/tilesCompsTemplates.jsp" />
+      <add-attribute value="/doc/portal/strutsIntegration.jsp" />
+      <add-attribute value="/doc/portal/comments.jsp" />
+      <add-attribute value="/doc/portal/revisions.jsp" />
+    </put-list-attribute>
+  </definition>
+
+  <!-- =======================================================  -->
+  <!-- Menus definitions  									-->
+  <!-- =======================================================  -->
+
+  <!-- Menu bar definition -->
+<definition name="doc.menu.main" template="/layout/vboxLayout.jsp" >
+  <put-list-attribute name="componentsList" >
+    <add-attribute value="doc.menu.links" />
+    <add-attribute value="doc.menu.taglib.references" />
+    <add-attribute value="doc.menu.printer.friendly" />
+    <add-attribute value="doc.menu.old.documents" />
+  </put-list-attribute>
+</definition>
+
+  <!-- Documentation menu definition v1.1-->
+<definition name="doc.menu.links" template="/layouts/menu.jsp" >
+  <put-attribute name="title" value="Documentation" />
+    <put-list-attribute name="items" >
+      <item value="Home"           link="/index.jsp"  />
+      <item value="Live Examples (new)" link="/examples/index.jsp"  />
+      <!--
+    <item> <value>Commented Examples</value>
+        <link>/examples/index.jsp</link>
+      <classtype>org.apache.tiles.beans.SimpleMenuItem</classtype>
+    </item>
+    -->
+      <item value="Quick overview" link="/doc/quickOverview.jsp"  />
+      <!--
+      <item value="Tutorial"       link="/doc/tutorial.jsp"  />
+      -->
+      <item value="Tutorial Live Examples" link="/tutorial/index.jsp" />
+      <item value="Download"       link="/doc/download.jsp" />
+      <item value="Installation"   link="/doc/installation.jsp" />
+      <item value="User Guide"	   link="/doc/userGuide.jsp" />
+      <item value="Javadoc"        link="/api/index.html" />
+      <item value="Struts Home"    link="http://www.apache.org"   icon="/images/struts-power.gif"
+      classtype="org.apache.tiles.beans.SimpleMenuItem" />
+    </put-list-attribute>
+</definition>
+
+  <!-- Printer friendly menu definition -->
+<definition name="doc.menu.printer.friendly" template="/layouts/menu.jsp" >
+  <put-attribute name="title" value="Printer Versions" />
+  <put-list-attribute name="items" >
+    <item value="Quick Overview"     link="/test/testAll.jsp" />
+    <item value="Tutorial"           link="/doc/tutorialBody.html" />
+    <item value="User Guide"         link="/doc/userGuideBody.html" />
+    <item value="Overview (old)"  	 link="/doc/overviewBody.html" />
+  </put-list-attribute>
+</definition>
+
+  <!-- Taglib menu definition -->
+<definition name="doc.menu.taglib.references" template="/layouts/menu.jsp" >
+  <put-attribute name="title" value="Tag Library Reference" />
+    <put-list-attribute name="items" >
+      <item value="Tiles Tags"     link="/doc/tilesTags.jsp" />
+      <!-- <item value="Extension Tags (old)"   link="/doc/extensionsTags.jsp" /> -->
+    </put-list-attribute>
+</definition>
+
+  <!-- Oldies menu definition -->
+<definition name="doc.menu.old.documents" template="/layouts/menu.jsp" >
+  <put-attribute name="title" value="Old Documents" />
+  <put-list-attribute name="items" >
+    <item value="Overview (old)"     link="/doc/overview.jsp" />
+  </put-list-attribute>
+</definition>
+
+
+</tiles-definitions>
diff --git a/Java-base/tiles/src/tiles-compat/src/test/resources/org/apache/tiles/config/tiles-defs-2.1.xml b/Java-base/tiles/src/tiles-compat/src/test/resources/org/apache/tiles/config/tiles-defs-2.1.xml
new file mode 100644
index 000000000..95668f8ed
--- /dev/null
+++ b/Java-base/tiles/src/tiles-compat/src/test/resources/org/apache/tiles/config/tiles-defs-2.1.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 2.1//EN"
+       "http://tiles.apache.org/dtds/tiles-config_2_1.dtd">
+
+<!-- Definitions for Tiles documentation   -->
+
+<tiles-definitions>
+  <definition name="doc.cascaded.test" template="/layout/classicLayout.jsp">
+    <put-attribute name="title" value="Test title" cascade="false" />
+    <put-attribute name="title2" value="Test title two" cascade="true" />
+    <put-list-attribute name="items1" cascade="false">
+        <add-attribute value="value1" type="string" />
+    </put-list-attribute>
+    <put-list-attribute name="items2" cascade="true">
+        <add-attribute value="value2" type="string" />
+    </put-list-attribute>
+  </definition>
+
+</tiles-definitions>
diff --git a/Java-base/tiles/src/tiles-core/pom.xml b/Java-base/tiles/src/tiles-core/pom.xml
new file mode 100644
index 000000000..8c376b10b
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/pom.xml
@@ -0,0 +1,139 @@
+<?xml version="1.0"?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+  <parent>
+    <groupId>org.apache.tiles</groupId>
+    <artifactId>tiles-parent</artifactId>
+    <version>3.1-SNAPSHOT</version>
+  </parent>
+
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>tiles-core</artifactId>
+  <packaging>jar</packaging>
+  <name>Tiles - Core Library</name>
+  <description>Tiles Core Library, including basic implementation of the APIs.
+  </description>
+
+  <properties>
+      <tiles.osgi.symbolicName>org.apache.tiles.core</tiles.osgi.symbolicName>
+      <!-- decrease this whenever possible -->
+      <checkstyle.maxAllowedViolations>25</checkstyle.maxAllowedViolations>
+  </properties>
+
+  <build>
+    <resources>
+      <resource>
+        <directory>src/main/resources</directory>
+        <excludes>
+          <exclude>LICENSE.txt</exclude>
+          <exclude>NOTICE.txt</exclude>
+        </excludes>
+      </resource>
+      <resource>
+        <directory>src/main/resources</directory>
+        <includes>
+          <include>LICENSE.txt</include>
+          <include>NOTICE.txt</include>
+        </includes>
+        <targetPath>META-INF</targetPath>
+      </resource>
+    </resources>
+
+  </build>
+
+  <reporting>
+    <plugins>
+      <plugin>
+        <groupId>net.sf.dtddoc</groupId>
+        <artifactId>dtddoc-maven-plugin</artifactId>
+        <version>1.1</version>
+        <configuration>
+          <docTitle>Tiles Definition File</docTitle>
+        </configuration>
+      </plugin>
+    </plugins>
+  </reporting>
+
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.tiles</groupId>
+      <artifactId>tiles-api</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>commons-digester</groupId>
+      <artifactId>commons-digester</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>jcl-over-slf4j</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-jdk14</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.easymock</groupId>
+      <artifactId>easymock</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.easymock</groupId>
+      <artifactId>easymockclassextension</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.shale</groupId>
+      <artifactId>shale-test</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>javax.servlet</groupId>
+      <artifactId>servlet-api</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+</project>
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/awareness/TilesContainerAware.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/awareness/TilesContainerAware.java
new file mode 100644
index 000000000..5c958b5c8
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/awareness/TilesContainerAware.java
@@ -0,0 +1,41 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.awareness;
+
+import org.apache.tiles.TilesContainer;
+
+/**
+ * It represents an object that can have a reference to the
+ * {@link TilesContainer}.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.1.0
+ */
+public interface TilesContainerAware {
+
+    /**
+     * Sets the Tiles container.
+     *
+     * @param container The Tiles container.
+     * @since 2.1.0
+     */
+    void setContainer(TilesContainer container);
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/awareness/package-info.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/awareness/package-info.java
new file mode 100644
index 000000000..faec1df1b
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/awareness/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * Interfaces that let the Tiles engine to inject dependencies to its objects.
+ */
+package org.apache.tiles.awareness;
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/context/TilesRequestContextHolder.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/context/TilesRequestContextHolder.java
new file mode 100644
index 000000000..e9497e3eb
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/context/TilesRequestContextHolder.java
@@ -0,0 +1,58 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.context;
+
+import org.apache.tiles.request.Request;
+
+/**
+ * Holds in a {@link ThreadLocal} object a {@link Request}.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public class TilesRequestContextHolder {
+
+    /**
+     * The Tiles request context holder.
+     */
+    private ThreadLocal<Request> requestHolder = new ThreadLocal<Request>();
+
+    /**
+     * Sets the Tiles request context to use.
+     *
+     * @param request The Tiles request.
+     * @since 2.2.0
+     */
+    public void setTilesRequestContext(Request request) {
+        requestHolder.set(request);
+    }
+
+    /**
+     * Returns the Tiles request context to use.
+     *
+     * @return The Tiles request.
+     * @since 2.2.0
+     */
+    public Request getTilesRequestContext() {
+        return requestHolder.get();
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/context/package-info.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/context/package-info.java
new file mode 100644
index 000000000..b25fa4f06
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/context/package-info.java
@@ -0,0 +1,25 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * Classes and interfaces that allow to access the various contexts in an
+ * application in a uniformed way.
+ */
+package org.apache.tiles.context;
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/DefinitionsFactory.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/DefinitionsFactory.java
new file mode 100644
index 000000000..2f52ada3d
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/DefinitionsFactory.java
@@ -0,0 +1,79 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition;
+
+import org.apache.tiles.Definition;
+import org.apache.tiles.request.Request;
+
+/**
+ * Interface for creating a {@link Definition}s and managing their contents.
+ * <p/>
+ * <p>
+ * DefinitionsFactory implementations are responsible for maintaining the data
+ * sources of Tiles configuration data and using the data to create Definitions
+ * sets. Implementations also know how to append locale-specific configuration
+ * data to an existing Definitions set.
+ * </p>
+ *
+ * @version $Rev$ $Date$
+ */
+public interface DefinitionsFactory {
+
+    /**
+     * Property name that specifies the implementation of the DefinitionsReader.
+     */
+    String READER_IMPL_PROPERTY =
+        "org.apache.tiles.definition.DefinitionsReader";
+
+    /**
+     * Property name that specifies the implementation of
+     * {@link org.apache.tiles.locale.LocaleResolver}.
+     */
+    String LOCALE_RESOLVER_IMPL_PROPERTY =
+        "org.apache.tiles.locale.LocaleResolver";
+
+    /**
+     * Constant representing the configuration parameter
+     * used to define the tiles definition resources.
+     *
+     * @since 2.1.0
+     */
+    String DEFINITIONS_CONFIG = "org.apache.tiles.definition.DefinitionsFactory.DEFINITIONS_CONFIG";
+
+    /**
+     * Constant representing the configuration parameter used to define the
+     * definition DAO to use.
+     */
+    String DEFINITION_DAO_INIT_PARAM =
+        "org.apache.tiles.definition.DefinitionsFactory.DefinitionDAO";
+
+    /**
+     * Returns a Definition object that matches the given name and
+     * Tiles context.
+     *
+     * @param name         The name of the Definition to return.
+     * @param tilesContext The Tiles context to use to resolve the definition.
+     * @return the Definition matching the given name or null if none
+     *         is found.
+     */
+    Definition getDefinition(String name, Request tilesContext);
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/DefinitionsFactoryException.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/DefinitionsFactoryException.java
new file mode 100644
index 000000000..bba845d56
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/DefinitionsFactoryException.java
@@ -0,0 +1,77 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+package org.apache.tiles.definition;
+
+import org.apache.tiles.TilesException;
+
+/**
+ * Exception thrown when an error occurs while the impl tries to
+ * create a new instance mapper.
+ *
+ * @version $Rev$ $Date$
+ */
+public class DefinitionsFactoryException extends TilesException {
+    /**
+     * Constructor.
+     */
+    public DefinitionsFactoryException() {
+        super();
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param message The error or warning message.
+     */
+    public DefinitionsFactoryException(String message) {
+        super(message);
+    }
+
+
+    /**
+     * Create a new <code>DefinitionsFactoryException</code> wrapping an existing exception.
+     * <p/>
+     * <p>The existing exception will be embedded in the new
+     * one and its message will become the default message for
+     * the DefinitionsFactoryException.</p>
+     *
+     * @param e The exception to be wrapped.
+     */
+    public DefinitionsFactoryException(Throwable e) {
+        super(e);
+    }
+
+
+    /**
+     * Create a new <code>DefinitionsFactoryException</code> from an existing exception.
+     * <p/>
+     * <p>The existing exception will be embedded in the new
+     * one, but the new exception will have its own message.</p>
+     *
+     * @param message The detail message.
+     * @param e       The exception to be wrapped.
+     */
+    public DefinitionsFactoryException(String message, Throwable e) {
+        super(message, e);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/DefinitionsReader.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/DefinitionsReader.java
new file mode 100644
index 000000000..3a3e5997e
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/DefinitionsReader.java
@@ -0,0 +1,56 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition;
+
+import java.util.Map;
+
+import org.apache.tiles.Definition;
+
+/**
+ * Interface for reading <code>{@link Definition}</code> from a source.
+ * <p/>
+ * <p>This interface provides a standard way to read
+ * <code>{@link Definition}</code> objects from a source.  Implementations
+ * should define what the source is, whether it be a persistent store such as a
+ * configuration file or database, or something like a web service.  The
+ * DefinitionsReader is responsible for reading from a single location.  It does
+ * not perform any internationalization duties or inheritance of Definitions.
+ * It only reads from the source and returns a Map of objects read.</p>
+ *
+ * @version $Rev$ $Date$
+ */
+public interface DefinitionsReader {
+
+    /**
+     * Reads <code>{@link Definition}</code> objects from a source.
+     * <p/>
+     * Implementations should publish what type of source object is expected.
+     *
+     * @param source The source from which definitions will be read.
+     * @return a Map of <code>Definition</code> objects read from
+     *         the source.
+     * @throws DefinitionsFactoryException if the source is invalid or
+     *                                     an error occurs when reading definitions.
+     */
+    Map<String, Definition> read(Object source);
+
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/FactoryNotFoundException.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/FactoryNotFoundException.java
new file mode 100644
index 000000000..d5df00b7d
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/FactoryNotFoundException.java
@@ -0,0 +1,65 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+package org.apache.tiles.definition;
+
+/**
+ * Exception thrown when definitions impl is not found.
+ *
+ * @version $Rev$ $Date$
+ */
+public class FactoryNotFoundException extends DefinitionsFactoryException {
+    /**
+     * Constructor.
+     */
+    public FactoryNotFoundException() {
+        super();
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param msg Message.
+     */
+    public FactoryNotFoundException(String msg) {
+        super(msg);
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param message Message.
+     * @param e Cause.
+     */
+    public FactoryNotFoundException(String message, Throwable e) {
+        super(message, e);
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param e Cause.
+     */
+    public FactoryNotFoundException(Throwable e) {
+        super(e);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/LocaleDefinitionsFactory.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/LocaleDefinitionsFactory.java
new file mode 100644
index 000000000..49b69dc1a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/LocaleDefinitionsFactory.java
@@ -0,0 +1,75 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition;
+
+import java.util.Locale;
+
+import org.apache.tiles.Definition;
+import org.apache.tiles.request.Request;
+
+/**
+ * {@link DefinitionsFactory DefinitionsFactory} implementation that manages
+ * Definitions configuration data from URLs, but resolving definition
+ * inheritance when a definition is returned.. <p/>
+ * <p>
+ * The Definition objects are read from the
+ * {@link org.apache.tiles.definition.digester.DigesterDefinitionsReader DigesterDefinitionsReader}
+ * class unless another implementation is specified.
+ * </p>
+ *
+ * @version $Rev$ $Date$
+ * @since 2.1.0
+ */
+public class LocaleDefinitionsFactory extends
+        UnresolvingLocaleDefinitionsFactory {
+
+    /** {@inheritDoc} */
+    @Override
+    public Definition getDefinition(String name,
+            Request tilesContext) {
+        Definition retValue;
+        Locale locale = null;
+
+        if (tilesContext != null) {
+            locale = localeResolver.resolveLocale(tilesContext);
+        }
+
+        retValue = definitionDao.getDefinition(name, locale);
+        if (retValue != null) {
+            retValue = new Definition(retValue);
+            String parentDefinitionName = retValue.getExtends();
+            while (parentDefinitionName != null) {
+                Definition parent = definitionDao.getDefinition(
+                        parentDefinitionName, locale);
+                if (parent == null) {
+                    throw new NoSuchDefinitionException("Cannot find definition '"
+                            + parentDefinitionName + "' ancestor of '"
+                            + retValue.getName() + "'");
+                }
+                retValue.inherit(parent);
+                parentDefinitionName = parent.getExtends();
+            }
+        }
+
+        return retValue;
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/NoSuchDefinitionException.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/NoSuchDefinitionException.java
new file mode 100644
index 000000000..a3e2f37e7
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/NoSuchDefinitionException.java
@@ -0,0 +1,65 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+package org.apache.tiles.definition;
+
+/**
+ * Exception thrown when a definition is not found.
+ *
+ * @version $Rev$ $Date$
+ */
+public class NoSuchDefinitionException extends DefinitionsFactoryException {
+    /**
+     * Constructor.
+     */
+    public NoSuchDefinitionException() {
+        super();
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param msg Message.
+     */
+    public NoSuchDefinitionException(String msg) {
+        super(msg);
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param message Message.
+     * @param e Cause.
+     */
+    public NoSuchDefinitionException(String message, Throwable e) {
+        super(message, e);
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param e Cause.
+     */
+    public NoSuchDefinitionException(Throwable e) {
+        super(e);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/RefreshMonitor.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/RefreshMonitor.java
new file mode 100644
index 000000000..d682ff62e
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/RefreshMonitor.java
@@ -0,0 +1,39 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.definition;
+
+/**
+ * Implementing this interface means that the object monitors the sources it
+ * uses to check when they change.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.1.0
+ */
+public interface RefreshMonitor {
+
+    /**
+     * Indicates whether the sources are out of date and need to be reloaded.
+     *
+     * @return <code>true</code> if the sources need to be refreshed.
+ * @since 2.1.0
+     */
+    boolean refreshRequired();
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/UnresolvingLocaleDefinitionsFactory.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/UnresolvingLocaleDefinitionsFactory.java
new file mode 100644
index 000000000..b2a691b7d
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/UnresolvingLocaleDefinitionsFactory.java
@@ -0,0 +1,91 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition;
+
+import java.util.Locale;
+
+import org.apache.tiles.Definition;
+import org.apache.tiles.definition.dao.DefinitionDAO;
+import org.apache.tiles.locale.LocaleResolver;
+import org.apache.tiles.request.Request;
+
+/**
+ * {@link DefinitionsFactory DefinitionsFactory} implementation that manages
+ * Definitions configuration data from URLs, without resolving definition
+ * inheritance when a definition is returned.<p/>
+ * <p>
+ * The Definition objects are read from the
+ * {@link org.apache.tiles.definition.digester.DigesterDefinitionsReader DigesterDefinitionsReader}
+ * class unless another implementation is specified.
+ * </p>
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.1
+ */
+public class UnresolvingLocaleDefinitionsFactory implements DefinitionsFactory {
+
+    /**
+     * The definition DAO that extracts the definitions from the sources.
+     *
+     * @since 2.2.1
+     */
+    protected DefinitionDAO<Locale> definitionDao;
+
+    /**
+     * The locale resolver object.
+     *
+     * @since 2.2.1
+     */
+    protected LocaleResolver localeResolver;
+
+    /**
+     * Sets the locale resolver to use.
+     *
+     * @param localeResolver The locale resolver.
+     * @since 2.2.1
+     */
+    public void setLocaleResolver(LocaleResolver localeResolver) {
+        this.localeResolver = localeResolver;
+    }
+
+    /**
+     * Sets the definition DAO to use. It must be locale-based.
+     *
+     * @param definitionDao The definition DAO.
+     * @since 2.2.1
+     */
+    public void setDefinitionDAO(DefinitionDAO<Locale> definitionDao) {
+        this.definitionDao = definitionDao;
+    }
+
+    /** {@inheritDoc} */
+    public Definition getDefinition(String name,
+            Request tilesContext) {
+        Locale locale = null;
+
+        if (tilesContext != null) {
+            locale = localeResolver.resolveLocale(tilesContext);
+        }
+
+        return definitionDao.getDefinition(name, locale);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/dao/BaseLocaleUrlDefinitionDAO.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/dao/BaseLocaleUrlDefinitionDAO.java
new file mode 100644
index 000000000..944f28773
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/dao/BaseLocaleUrlDefinitionDAO.java
@@ -0,0 +1,172 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition.dao;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.tiles.Definition;
+import org.apache.tiles.definition.DefinitionsFactoryException;
+import org.apache.tiles.definition.DefinitionsReader;
+import org.apache.tiles.definition.RefreshMonitor;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.ApplicationResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Base abstract class for a DAO that is based on URLs and locale as a
+ * customization key.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.1.0
+ */
+public abstract class BaseLocaleUrlDefinitionDAO implements
+        DefinitionDAO<Locale>, RefreshMonitor {
+
+    /**
+     * The logging object.
+     */
+    private final Logger log = LoggerFactory
+            .getLogger(BaseLocaleUrlDefinitionDAO.class);
+
+    /**
+     * Contains the URL objects identifying where configuration data is found.
+     *
+     * @since 2.1.0
+     */
+    protected List<ApplicationResource> sources;
+
+    /**
+     * Contains the dates that the URL sources were last modified.
+     *
+     * @since 2.1.0
+     */
+    protected Map<String, Long> lastModifiedDates;
+
+    /**
+     * Reader used to get definitions from the sources.
+     *
+     * @since 2.1.0
+     */
+    protected DefinitionsReader reader;
+
+    /**
+     * ApplicationContext to locate the source files.
+     *
+     * @since 3.0.0
+     */
+    protected ApplicationContext applicationContext;
+
+    /**
+     * Constructor.
+     */
+    public BaseLocaleUrlDefinitionDAO(ApplicationContext applicationContext) {
+        this.applicationContext = applicationContext;
+        lastModifiedDates = new HashMap<String, Long>();
+    }
+
+    public void setSources(List<ApplicationResource> sources) {
+        // filter out any sources that are already localized
+        ArrayList<ApplicationResource> defaultSources = new ArrayList<ApplicationResource>();
+        for(ApplicationResource source: sources) {
+            if(Locale.ROOT.equals(source.getLocale())) {
+                defaultSources.add(source);
+            }
+        }
+        this.sources = defaultSources;
+    }
+
+    public void setReader(DefinitionsReader reader) {
+        this.reader = reader;
+    }
+
+    /** {@inheritDoc} */
+    public boolean refreshRequired() {
+        boolean status = false;
+
+        Set<String> paths = lastModifiedDates.keySet();
+
+        try {
+            for (String path : paths) {
+                Long lastModifiedDate = lastModifiedDates.get(path);
+                ApplicationResource resource = applicationContext.getResource(path);
+                long newModDate = resource.getLastModified();
+                if (newModDate != lastModifiedDate) {
+                    status = true;
+                    break;
+                }
+            }
+        } catch (IOException e) {
+            log.warn("Exception while monitoring update times.", e);
+            return true;
+        }
+        return status;
+    }
+
+    /**
+     * Loads definitions from an URL without loading from "parent" URLs.
+     *
+     * @param resource The URL to read.
+     * @return The definition map that has been read.
+     */
+    protected Map<String, Definition> loadDefinitionsFromResource(ApplicationResource resource) {
+        Map<String, Definition> defsMap = null;
+
+        InputStream stream = null;
+        try {
+            lastModifiedDates.put(resource.getLocalePath(), resource
+                    .getLastModified());
+
+            // Definition must be collected, starting from the base
+            // source up to the last localized file.
+            stream = resource.getInputStream();
+            defsMap = reader.read(stream);
+        } catch (FileNotFoundException e) {
+            // File not found. continue.
+            if (log.isDebugEnabled()) {
+                log.debug("File " + resource.toString() + " not found, continue");
+            }
+        } catch (IOException e) {
+            throw new DefinitionsFactoryException(
+                    "I/O error processing configuration.", e);
+        } finally {
+            try {
+                if (stream != null) {
+                    stream.close();
+                }
+            } catch (IOException e) {
+                throw new DefinitionsFactoryException(
+                        "I/O error closing " + resource.toString(), e);
+            }
+        }
+
+        return defsMap;
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/dao/CachingLocaleUrlDefinitionDAO.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/dao/CachingLocaleUrlDefinitionDAO.java
new file mode 100644
index 000000000..20f13db8d
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/dao/CachingLocaleUrlDefinitionDAO.java
@@ -0,0 +1,272 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition.dao;
+
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.tiles.Definition;
+import org.apache.tiles.definition.pattern.PatternDefinitionResolver;
+import org.apache.tiles.definition.pattern.PatternDefinitionResolverAware;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.ApplicationResource;
+import org.apache.tiles.request.locale.LocaleUtil;
+
+/**
+ * <p>
+ * A definitions DAO (loading URLs and using Locale as a customization key) that
+ * caches definitions that have been loaded in a raw way (i.e. with inheritance
+ * that is not resolved).
+ * </p>
+ * <p>
+ * It can check if the URLs change, but by default this feature is turned off.
+ * </p>
+ *
+ * @version $Rev$ $Date$
+ * @since 2.1.0
+ */
+public class CachingLocaleUrlDefinitionDAO extends BaseLocaleUrlDefinitionDAO
+        implements PatternDefinitionResolverAware<Locale> {
+
+    /**
+     * Initialization parameter to set whether we want to refresh URLs when they
+     * change.
+     *
+     * @since 2.1.0
+     */
+    public static final String CHECK_REFRESH_INIT_PARAMETER =
+        "org.apache.tiles.definition.dao.LocaleUrlDefinitionDAO.CHECK_REFRESH";
+
+    /**
+     * The locale-specific set of definitions objects.
+     *
+     * @since 2.1.0
+     */
+    protected Map<Locale, Map<String, Definition>> locale2definitionMap;
+
+    /**
+     * Flag that, when <code>true</code>, enables automatic checking of URLs
+     * changing.
+     *
+     * @since 2.1.0
+     */
+    protected boolean checkRefresh = false;
+
+    /**
+     * Resolves definitions using patterns.
+     *
+     * @since 2.2.0
+     */
+    protected PatternDefinitionResolver<Locale> definitionResolver;
+
+    /**
+     * Constructor.
+     *
+     * @since 2.1.0
+     */
+    public CachingLocaleUrlDefinitionDAO(ApplicationContext applicationContext) {
+        super(applicationContext);
+        locale2definitionMap = new HashMap<Locale, Map<String, Definition>>();
+    }
+
+    /** {@inheritDoc} */
+    public void setPatternDefinitionResolver(
+            PatternDefinitionResolver<Locale> definitionResolver) {
+        this.definitionResolver = definitionResolver;
+    }
+
+    /** {@inheritDoc} */
+    public Definition getDefinition(String name, Locale customizationKey) {
+        Definition retValue = null;
+        if (customizationKey == null) {
+            customizationKey = Locale.ROOT;
+        }
+        Map<String, Definition> definitions = getDefinitions(customizationKey);
+        if (definitions != null) {
+            retValue = definitions.get(name);
+
+            if (retValue == null) {
+                retValue = getDefinitionFromResolver(name, customizationKey);
+
+                if (retValue != null) {
+                    synchronized (definitions) {
+                        definitions.put(name, retValue);
+                    }
+                }
+            }
+        }
+
+        return retValue;
+    }
+
+    /** {@inheritDoc} */
+    public Map<String, Definition> getDefinitions(Locale customizationKey) {
+        if (customizationKey == null) {
+            customizationKey = Locale.ROOT;
+        }
+        Map<String, Definition> retValue = locale2definitionMap
+                .get(customizationKey);
+        if (retValue == null || (checkRefresh && refreshRequired())) {
+            retValue = checkAndloadDefinitions(customizationKey);
+        }
+        return retValue;
+    }
+
+    /**
+     * Sets the flag to check source refresh. If not called, the default is
+     * <code>false</code>.
+     *
+     * @param checkRefresh When <code>true</code>, enables automatic checking
+     * of sources changing.
+     * @since 2.1.0
+     */
+    public void setCheckRefresh(boolean checkRefresh) {
+        this.checkRefresh = checkRefresh;
+    }
+
+    /**
+     * Returns a definition from the definition resolver.
+     *
+     * @param name The name of the definition.
+     * @param customizationKey The customization key to use.
+     * @return The resolved definition.
+     */
+    protected Definition getDefinitionFromResolver(String name,
+            Locale customizationKey) {
+        return definitionResolver.resolveDefinition(name,
+                customizationKey);
+    }
+
+    /**
+     * Checks if sources have changed. If yes, it clears the cache. Then continues
+     * loading definitions.
+     *
+     * @param customizationKey The locale to use when loading sources.
+     * @return The loaded definitions.
+     * @since 2.1.0
+     */
+    protected synchronized Map<String, Definition> checkAndloadDefinitions(Locale customizationKey) {
+        Map<String, Definition> existingDefinitions = locale2definitionMap.get(customizationKey);
+        boolean definitionsAlreadyLoaded = existingDefinitions != null;
+        if (definitionsAlreadyLoaded) {
+            return existingDefinitions;
+        }
+        if (checkRefresh && refreshRequired()) {
+            locale2definitionMap.clear();
+            definitionResolver.clearPatternPaths(customizationKey);
+        }
+        loadDefinitions(customizationKey);
+        return locale2definitionMap.get(customizationKey);
+    }
+
+    /**
+     * Tries to load definitions if necessary.
+     *
+     * @param customizationKey The locale to use when loading sources.
+     * @return The loaded definitions.
+     * @since 2.1.0
+     */
+    protected Map<String, Definition> loadDefinitions(Locale customizationKey) {
+        Map<String, Definition> localeDefsMap = locale2definitionMap
+                .get(customizationKey);
+        if (localeDefsMap != null) {
+            return localeDefsMap;
+        }
+
+        return loadDefinitionsFromResources(customizationKey);
+    }
+
+    /**
+     * Loads definitions from the sources.
+     *
+     * @param customizationKey The locale to use when loading Resources.
+     * @return The loaded definitions.
+     * @since 2.1.0
+     */
+    protected Map<String, Definition> loadDefinitionsFromResources(Locale customizationKey) {
+        Map<String, Definition> localeDefsMap = loadRawDefinitionsFromResources(customizationKey);
+        Map<String, Definition> defsMap = definitionResolver
+                .storeDefinitionPatterns(copyDefinitionMap(localeDefsMap),
+                        customizationKey);
+        locale2definitionMap.put(customizationKey, defsMap);
+        return localeDefsMap;
+    }
+
+    /**
+     * Loads the raw definitions from the sources associated with a locale.
+     *
+     * @param customizationKey The locale to use when loading Resources.
+     * @return The loaded definitions.
+     * @since 2.1.3
+     */
+    protected Map<String, Definition> loadRawDefinitionsFromResources(
+            Locale customizationKey) {
+        Map<String, Definition> localeDefsMap;
+
+        Locale parentLocale = LocaleUtil.getParentLocale(customizationKey);
+        localeDefsMap = new LinkedHashMap<String, Definition>();
+        if (parentLocale != null) {
+            Map<String, Definition> parentDefs = loadRawDefinitionsFromResources(parentLocale);
+            if (parentDefs != null) {
+                localeDefsMap.putAll(parentDefs);
+            }
+        }
+        // For each source, the resource must be loaded.
+        for (ApplicationResource resource : sources) {
+            ApplicationResource newResource = applicationContext.getResource(resource, customizationKey);
+            if (newResource != null) {
+                Map<String, Definition> defsMap = loadDefinitionsFromResource(newResource);
+                if (defsMap != null) {
+                    localeDefsMap.putAll(defsMap);
+                }
+            }
+        }
+        return localeDefsMap;
+    }
+
+    /**
+     * Loads parent definitions, i.e. definitions mapped to a parent locale.
+     *
+     * @param parentLocale The locale to use when loading URLs.
+     * @return The loaded parent definitions.
+     * @since 2.1.0
+     */
+    protected Map<String, Definition> loadParentDefinitions(Locale parentLocale) {
+        return loadDefinitions(parentLocale);
+    }
+
+    /**
+     * Copies the definition map to be passed to a higher level of customization
+     * key.
+     *
+     * @param localeDefsMap The map of definition to be copied.
+     * @return The copy of the definition map. This particular implementation
+     * return the <code>localeDefsMap</code> itself.
+     * @since 2.1.4
+     */
+    protected Map<String, Definition> copyDefinitionMap(
+            Map<String, Definition> localeDefsMap) {
+        return localeDefsMap;
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/dao/DefinitionDAO.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/dao/DefinitionDAO.java
new file mode 100644
index 000000000..a5461e4e7
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/dao/DefinitionDAO.java
@@ -0,0 +1,57 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.definition.dao;
+
+import java.util.Map;
+
+import org.apache.tiles.Definition;
+
+/**
+ * It represents an object that provides definitions, depending on a
+ * customization key.
+ *
+ * @param <K> The customization key class.
+ * @version $Rev$ $Date$
+ * @since 2.1.0
+ */
+public interface DefinitionDAO<K> {
+
+    /**
+     * Returns a definition, given its name and the customization key.
+     *
+     * @param name The name of the definition.
+     * @param customizationKey The customization key.
+     * @return The requested definition, if found, otherwise <code>null</code>.
+     * The inheritance of the definition must not be resolved.
+     * @since 2.1.0
+     */
+    Definition getDefinition(String name, K customizationKey);
+
+    /**
+     * Returns all the definitions used of a customization key.
+     *
+     * @param customizationKey The customization key.
+     * @return All the definitions that are connected to the customization key.
+     * The inheritance of the definitions must not be resolved.
+     * @since 2.1.0
+     */
+    Map<String, Definition> getDefinitions(K customizationKey);
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/dao/LocaleUrlDefinitionDAO.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/dao/LocaleUrlDefinitionDAO.java
new file mode 100644
index 000000000..4f50437f3
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/dao/LocaleUrlDefinitionDAO.java
@@ -0,0 +1,105 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.definition.dao;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.tiles.Definition;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.ApplicationResource;
+import org.apache.tiles.request.locale.LocaleUtil;
+
+/**
+ * A definition DAO that uses {@link Locale} as a customization key and loads
+ * definitions from URLs. It does not cache definitions in any way.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.1.0
+ */
+public class LocaleUrlDefinitionDAO extends BaseLocaleUrlDefinitionDAO {
+
+    public LocaleUrlDefinitionDAO(ApplicationContext applicationContext) {
+        super(applicationContext);
+    }
+
+    /**
+     * <p>
+     * Returns a definition, given its name and the customization key.
+     * </p>
+     * <strong>WARNING!</strong> This method is slow! It loads all the
+     * definitions and then selects the needed one.
+     *
+     * @param name The name of the definition.
+     * @param customizationKey The customization key.
+     * @return The requested definition, if found, otherwise <code>null</code>.
+     * The inheritance of the definition must not be resolved.
+     * @since 2.1.0
+     */
+    public Definition getDefinition(String name, Locale customizationKey) {
+        Map<String, Definition> defsMap = getDefinitions(customizationKey);
+        return defsMap.get(name);
+    }
+
+    /** {@inheritDoc} */
+    public Map<String, Definition> getDefinitions(Locale customizationKey) {
+        ArrayList<Locale> postfixes = computeLocales(customizationKey);
+        Map<String, Definition> localeDefsMap = new HashMap<String, Definition>();
+        // process the postfixes from the root to the most specific
+        for (Locale postfix : postfixes) {
+            // For each postfix, all the sources must be loaded.
+            for (ApplicationResource resource : sources) {
+                ApplicationResource newResource = applicationContext.getResource(resource, postfix);
+                if (newResource != null) {
+                    Map<String, Definition> defsMap = loadDefinitionsFromResource(newResource);
+                    if (defsMap != null) {
+                        localeDefsMap.putAll(defsMap);
+                    }
+                }
+            }
+        }
+        return localeDefsMap;
+    }
+
+    /**
+     * Returns a list of locales from root to the customizationKey.
+     * @param customizationKey the target Locale.
+     * @return the list of its ancestors.
+     */
+    private ArrayList<Locale> computeLocales(Locale customizationKey) {
+        Locale postfix;
+        if(customizationKey == null) {
+            postfix = Locale.ROOT;
+        } else {
+            postfix = customizationKey;
+        }
+        ArrayList<Locale> postfixes = new ArrayList<Locale>();
+        while (postfix != null) {
+            postfixes.add(postfix);
+            postfix = LocaleUtil.getParentLocale(postfix);
+        }
+        Collections.reverse(postfixes);
+        return postfixes;
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/dao/ResolvingLocaleUrlDefinitionDAO.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/dao/ResolvingLocaleUrlDefinitionDAO.java
new file mode 100644
index 000000000..7c7b35279
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/dao/ResolvingLocaleUrlDefinitionDAO.java
@@ -0,0 +1,178 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition.dao;
+
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.tiles.Definition;
+import org.apache.tiles.definition.NoSuchDefinitionException;
+import org.apache.tiles.request.ApplicationContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * <p>
+ * A definitions DAO (loading URLs and using Locale as a customization key) that
+ * caches definitions that have been loaded and resolves inheritances.
+ * </p>
+ * <p>
+ * It can check if the URLs change, but by default this feature is turned off.
+ * </p>
+ *
+ * @version $Rev$ $Date$
+ * @since 2.1.0
+ */
+public class ResolvingLocaleUrlDefinitionDAO extends
+        CachingLocaleUrlDefinitionDAO {
+
+    /**
+     * The logging object.
+     */
+    private final Logger log = LoggerFactory.getLogger(ResolvingLocaleUrlDefinitionDAO.class);
+
+    public ResolvingLocaleUrlDefinitionDAO(ApplicationContext applicationContext) {
+        super(applicationContext);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected Map<String, Definition> loadParentDefinitions(Locale parentLocale) {
+        return loadRawDefinitionsFromResources(parentLocale);
+    }
+
+    @Override
+    protected Map<String, Definition> loadDefinitions(Locale customizationKey) {
+        Map<String, Definition> localeDefsMap = super.loadDefinitions(customizationKey);
+        Map<String, Definition> defsMap = definitionResolver
+                .storeDefinitionPatterns(copyDefinitionMap(localeDefsMap),
+                        customizationKey);
+        resolveInheritances(defsMap, customizationKey);
+        locale2definitionMap.put(customizationKey, defsMap);
+        return defsMap;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected Definition getDefinitionFromResolver(String name,
+            Locale customizationKey) {
+        Definition retValue = super.getDefinitionFromResolver(name, customizationKey);
+        if (retValue != null && retValue.getExtends() != null) {
+            Definition parent = getDefinition(retValue.getExtends(), customizationKey);
+            retValue.inherit(parent);
+        }
+
+        return retValue;
+    }
+
+    /**
+     * Resolve locale-specific extended instances.
+     *
+     * @param map The definition map containing the definitions to resolve.
+     * @param locale The locale to use.
+     * @throws NoSuchDefinitionException If a parent definition is not found.
+     * @since 2.1.0
+     */
+    protected void resolveInheritances(Map<String, Definition> map, Locale locale) {
+        if (map != null) {
+            Set<String> alreadyResolvedDefinitions = new HashSet<String>();
+            for (Definition definition : map.values()) {
+                resolveInheritance(definition, map, locale,
+                        alreadyResolvedDefinitions);
+            }  // end loop
+        }
+    }
+
+    /**
+     * Resolve locale-specific inheritance. First, resolve parent's inheritance,
+     * then set template to the parent's template. Also copy attributes setted
+     * in parent, and not set in child If instance doesn't extend anything, do
+     * nothing.
+     *
+     * @param definition The definition to resolve
+     * @param definitions The definitions to take when obtaining a parent
+     * definition.
+     * @param locale The locale to use.
+     * @param alreadyResolvedDefinitions The set of the definitions that have
+     * been already resolved.
+     * @throws NoSuchDefinitionException If an inheritance can not be solved.
+     * @since 2.1.0
+     */
+    protected void resolveInheritance(Definition definition,
+            Map<String, Definition> definitions, Locale locale,
+            Set<String> alreadyResolvedDefinitions) {
+        // Already done, or not needed ?
+        if (!definition.isExtending()
+                || alreadyResolvedDefinitions.contains(definition.getName())) {
+            return;
+        }
+
+        log.debug("Resolve definition for child name='{}' extends='{}.",
+                definition.getName(), definition.getExtends());
+
+        // Set as visited to avoid endless recursivity.
+        alreadyResolvedDefinitions.add(definition.getName());
+
+        // Resolve parent before itself.
+        Definition parent = definitions.get(definition.getExtends());
+        if (parent == null) { // error
+            String msg = "Error while resolving definition inheritance: child '"
+                + definition.getName()
+                + "' can't find its ancestor '"
+                + definition.getExtends()
+                + "'. Please check your description file.";
+            // to do : find better exception
+            throw new NoSuchDefinitionException(msg);
+        }
+
+        resolveInheritance(parent, definitions, locale,
+                alreadyResolvedDefinitions);
+
+        definition.inherit(parent);
+    }
+
+    /**
+     * Copies the definition map to be passed to a higher level of customization
+     * key.
+     *
+     * @param localeDefsMap The map of definition to be copied.
+     * @return The copy of the definition map. This particular implementation
+     * deep-copies the <code>localeDefsMap</code> into a {@link LinkedHashMap}.
+     * @since 2.1.4
+     */
+    @Override
+    protected Map<String, Definition> copyDefinitionMap(
+            Map<String, Definition> localeDefsMap) {
+        Map<String, Definition> retValue = new LinkedHashMap<String, Definition>(
+                localeDefsMap.size());
+
+        for (Map.Entry<String, Definition> entry : localeDefsMap.entrySet()) {
+            Definition definition = new Definition(entry.getValue());
+            retValue.put(entry.getKey(), definition);
+        }
+
+        return retValue;
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/dao/package-info.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/dao/package-info.java
new file mode 100644
index 000000000..61ec23e20
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/dao/package-info.java
@@ -0,0 +1,25 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * Classes to simply load definitions depending on a customization key.
+ * The package contains also basic implementations.
+ */
+package org.apache.tiles.definition.dao;
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/digester/DigesterDefinitionsReader.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/digester/DigesterDefinitionsReader.java
new file mode 100644
index 000000000..b7c4560dc
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/digester/DigesterDefinitionsReader.java
@@ -0,0 +1,470 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition.digester;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.apache.commons.digester.Digester;
+import org.apache.commons.digester.Rule;
+import org.apache.tiles.Attribute;
+import org.apache.tiles.Definition;
+import org.apache.tiles.Expression;
+import org.apache.tiles.ListAttribute;
+import org.apache.tiles.definition.DefinitionsFactoryException;
+import org.apache.tiles.definition.DefinitionsReader;
+import org.xml.sax.Attributes;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+/**
+ * Reads {@link Definition} objects from
+ * an XML InputStream using Digester. <p/>
+ * <p>
+ * This <code>DefinitionsReader</code> implementation expects the source to be
+ * passed as an <code>InputStream</code>. It parses XML data from the source
+ * and builds a Map of Definition objects.
+ * </p>
+ * <p/>
+ * <p>
+ * The Digester object can be configured by passing in initialization
+ * parameters. Currently the only parameter that is supported is the
+ * <code>validating</code> parameter. This value is set to <code>false</code>
+ * by default. To enable DTD validation for XML Definition files, give the init
+ * method a parameter with a key of
+ * <code>org.apache.tiles.definition.digester.DigesterDefinitionsReader.PARSER_VALIDATE</code>
+ * and a value of <code>&quot;true&quot;</code>. <p/>
+ * <p>
+ * The Definition objects are stored internally in a Map. The Map is stored as
+ * an instance variable rather than a local variable in the <code>read</code>
+ * method. This means that instances of this class are <strong>not</strong>
+ * thread-safe and access by multiple threads must be synchronized.
+ * </p>
+ *
+ * @version $Rev$ $Date$
+ */
+public class DigesterDefinitionsReader implements DefinitionsReader {
+
+    /**
+     * Digester validation parameter name.
+     */
+    public static final String PARSER_VALIDATE_PARAMETER_NAME =
+        "org.apache.tiles.definition.digester.DigesterDefinitionsReader.PARSER_VALIDATE";
+
+    // Digester rules constants for tag interception.
+
+    /**
+     * Intercepts a &lt;definition&gt; tag.
+     */
+    private static final String DEFINITION_TAG = "tiles-definitions/definition";
+
+    /**
+     * Intercepts a &lt;put-attribute&gt; tag.
+     */
+    private static final String PUT_TAG = "*/definition/put-attribute";
+
+    /**
+     * Intercepts a &lt;definition&gt; inside a  &lt;put-attribute&gt; tag.
+     */
+    private static final String PUT_DEFINITION_TAG = "*/put-attribute/definition";
+
+    /**
+     * Intercepts a &lt;definition&gt; inside an &lt;add-attribute&gt; tag.
+     */
+    private static final String ADD_DEFINITION_TAG = "*/add-attribute/definition";
+
+    /**
+     * Intercepts a &lt;put-list-attribute&gt; tag inside a %lt;definition&gt;
+     * tag.
+     */
+    private static final String DEF_LIST_TAG = "*/definition/put-list-attribute";
+
+    /**
+     * Intercepts a &lt;add-attribute&gt; tag.
+     */
+    private static final String ADD_LIST_ELE_TAG = "*/add-attribute";
+
+    /**
+     * Intercepts a &lt;add-list-attribute&gt; tag.
+     */
+    private static final String NESTED_LIST = "*/add-list-attribute";
+
+    // Handler class names.
+
+    /**
+     * The handler to create definitions.
+     *
+     * @since 2.1.0
+     */
+    protected static final String DEFINITION_HANDLER_CLASS =
+        Definition.class.getName();
+
+    /**
+     * The handler to create attributes.
+     *
+     * @since 2.1.0
+     */
+    protected static final String PUT_ATTRIBUTE_HANDLER_CLASS =
+        Attribute.class.getName();
+
+    /**
+     * The handler to create list attributes.
+     *
+     * @since 2.1.0
+     */
+    protected static final String LIST_HANDLER_CLASS =
+        ListAttribute.class.getName();
+
+    /**
+     * Digester rule to manage definition filling.
+     *
+     * @since 2.1.2
+     */
+    public static class FillDefinitionRule extends Rule {
+
+        /** {@inheritDoc} */
+        @Override
+        public void begin(String namespace, String name, Attributes attributes) {
+            Definition definition = (Definition) digester.peek();
+            definition.setName(attributes.getValue("name"));
+            definition.setPreparer(attributes.getValue("preparer"));
+            String extendsAttribute = attributes.getValue("extends");
+            definition.setExtends(extendsAttribute);
+
+            String template = attributes.getValue("template");
+            Attribute attribute = Attribute.createTemplateAttribute(template);
+            attribute.setExpressionObject(Expression
+                    .createExpressionFromDescribedExpression(attributes
+                            .getValue("templateExpression")));
+            attribute.setRole(attributes.getValue("role"));
+            String templateType = attributes.getValue("templateType");
+            if (templateType != null) {
+                attribute.setRenderer(templateType);
+            } else if (extendsAttribute != null && templateType == null) {
+                attribute.setRenderer(null);
+            }
+            definition.setTemplateAttribute(attribute);
+        }
+    }
+
+    /**
+     * Digester rule to manage attribute filling.
+     *
+     * @since 2.1.0
+     */
+    public static class FillAttributeRule extends Rule {
+
+        /** {@inheritDoc} */
+        @Override
+        public void begin(String namespace, String name, Attributes attributes) {
+            Attribute attribute = (Attribute) digester.peek();
+            attribute.setValue(attributes.getValue("value"));
+            String expression = attributes.getValue("expression");
+            attribute.setExpressionObject(Expression
+                    .createExpressionFromDescribedExpression(expression));
+            attribute.setRole(attributes.getValue("role"));
+            attribute.setRenderer(attributes.getValue("type"));
+        }
+    }
+
+    /**
+     * Digester rule to manage assignment of the attribute to the parent
+     * element.
+     *
+     * @since 2.1.0
+     */
+    public static class PutAttributeRule extends Rule {
+
+        /** {@inheritDoc} */
+        @Override
+        public void begin(String namespace, String name, Attributes attributes) {
+            Attribute attribute = (Attribute) digester.peek(0);
+            Definition definition = (Definition) digester.peek(1);
+            definition.putAttribute(attributes.getValue("name"), attribute,
+                    "true".equals(attributes.getValue("cascade")));
+        }
+    }
+
+    /**
+     * Digester rule to manage assignment of a nested definition in an attribute
+     * value.
+     *
+     * @since 2.1.0
+     */
+    public class AddNestedDefinitionRule extends Rule {
+
+        /** {@inheritDoc} */
+        @Override
+        public void begin(String namespace, String name, Attributes attributes) {
+            Definition definition = (Definition) digester.peek(0);
+            if (definition.getName() == null) {
+                definition.setName(getNextUniqueDefinitionName(definitions));
+            }
+            Attribute attribute = (Attribute) digester.peek(1);
+            attribute.setValue(definition.getName());
+            attribute.setRenderer("definition");
+        }
+    }
+
+    /**
+     * <code>Digester</code> object used to read Definition data
+     * from the source.
+     */
+    protected Digester digester;
+
+    /**
+     * The set of public identifiers, and corresponding resource names for
+     * the versions of the configuration file DTDs we know about.  There
+     * <strong>MUST</strong> be an even number of Strings in this list!
+     */
+    protected String[] registrations;
+
+    /**
+     * Stores Definition objects.
+     */
+    private Map<String, Definition> definitions;
+
+    /**
+     * Index to be used to create unique definition names for anonymous
+     * (nested) definitions.
+     */
+    private int anonymousDefinitionIndex = 1;
+
+    /**
+     * Creates a new instance of DigesterDefinitionsReader.
+     */
+    public DigesterDefinitionsReader() {
+        digester = new Digester();
+        digester.setNamespaceAware(true);
+        digester.setUseContextClassLoader(true);
+        digester.setErrorHandler(new ThrowingErrorHandler());
+
+        // Register our local copy of the DTDs that we can find
+        String[] registrations = getRegistrations();
+        for (int i = 0; i < registrations.length; i += 2) {
+            URL url = this.getClass().getResource(
+                registrations[i + 1]);
+            if (url != null) {
+                digester.register(registrations[i], url.toString());
+            }
+        }
+
+        initSyntax(digester);
+    }
+
+    /**
+     * Sets the validation of XML files.
+     *
+     * @param validating <code>true</code> means that XML validation is turned
+     * on. <code>false</code> otherwise.
+     * @since 3.3.0
+     */
+    public void setValidating(boolean validating) {
+        digester.setValidating(validating);
+    }
+
+    /**
+     * Reads <code>{@link Definition}</code> objects from a source.
+     * <p/>
+     * Implementations should publish what type of source object is expected.
+     *
+     * @param source The <code>InputStream</code> source from which definitions
+     *               will be read.
+     * @return a Map of <code>Definition</code> objects read from
+     *         the source.
+     * @throws DefinitionsFactoryException If the source is invalid or
+     *          an error occurs when reading definitions.
+     */
+    public Map<String, Definition> read(Object source) {
+        // This is an instance variable instead of a local variable because
+        // we want to be able to call the addDefinition method to populate it.
+        // But we reset the Map here, which, of course, has threading implications.
+        definitions = new LinkedHashMap<String, Definition>();
+
+        if (source == null) {
+            // Perhaps we should throw an exception here.
+            return null;
+        }
+
+        InputStream input;
+        try {
+            input = (InputStream) source;
+        } catch (ClassCastException e) {
+            throw new DefinitionsFactoryException(
+                "Invalid source type.  Requires java.io.InputStream.", e);
+        }
+
+        try {
+            // set first object in stack
+            //digester.clear();
+            digester.push(this);
+            // parse
+            digester.parse(input);
+
+        } catch (SAXException e) {
+            throw new DefinitionsFactoryException(
+                "XML error reading definitions.", e);
+        } catch (IOException e) {
+            throw new DefinitionsFactoryException(
+                "I/O Error reading definitions.", e);
+        } finally {
+            digester.clear();
+        }
+
+        return definitions;
+    }
+
+    /**
+     * Initialised the syntax for reading XML files containing Tiles
+     * definitions.
+     *
+     * @param digester The digester to initialize.
+     */
+    protected void initSyntax(Digester digester) {
+        initDigesterForTilesDefinitionsSyntax(digester);
+    }
+
+
+    /**
+     * Init digester for Tiles syntax with first element = tiles-definitions.
+     *
+     * @param digester Digester instance to use.
+     */
+    private void initDigesterForTilesDefinitionsSyntax(Digester digester) {
+        // syntax rules
+        digester.addObjectCreate(DEFINITION_TAG, DEFINITION_HANDLER_CLASS);
+        digester.addRule(DEFINITION_TAG, new FillDefinitionRule());
+        digester.addSetNext(DEFINITION_TAG, "addDefinition", DEFINITION_HANDLER_CLASS);
+
+        // nested definition rules
+        digester.addObjectCreate(PUT_DEFINITION_TAG, DEFINITION_HANDLER_CLASS);
+        digester.addRule(PUT_DEFINITION_TAG, new FillDefinitionRule());
+        digester.addSetRoot(PUT_DEFINITION_TAG, "addDefinition");
+        digester.addRule(PUT_DEFINITION_TAG, new AddNestedDefinitionRule());
+        digester.addObjectCreate(ADD_DEFINITION_TAG, DEFINITION_HANDLER_CLASS);
+        digester.addRule(ADD_DEFINITION_TAG, new FillDefinitionRule());
+        digester.addSetRoot(ADD_DEFINITION_TAG, "addDefinition");
+        digester.addRule(ADD_DEFINITION_TAG, new AddNestedDefinitionRule());
+
+        // put / putAttribute rules
+        // Rules for a same pattern are called in order, but rule.end() are called
+        // in reverse order.
+        // SetNext and CallMethod use rule.end() method. So, placing SetNext in
+        // first position ensure it will be called last (sic).
+        digester.addObjectCreate(PUT_TAG, PUT_ATTRIBUTE_HANDLER_CLASS);
+        digester.addRule(PUT_TAG, new FillAttributeRule());
+        digester.addRule(PUT_TAG, new PutAttributeRule());
+        // Definition level list rules
+        // This is rules for lists nested in a definition
+        digester.addObjectCreate(DEF_LIST_TAG, LIST_HANDLER_CLASS);
+        digester.addSetProperties(DEF_LIST_TAG);
+        digester.addRule(DEF_LIST_TAG, new PutAttributeRule());
+        // list elements rules
+        // We use Attribute class to avoid rewriting a new class.
+        // Name part can't be used in listElement attribute.
+        digester.addObjectCreate(ADD_LIST_ELE_TAG, PUT_ATTRIBUTE_HANDLER_CLASS);
+        digester.addRule(ADD_LIST_ELE_TAG, new FillAttributeRule());
+        digester.addSetNext(ADD_LIST_ELE_TAG, "add", PUT_ATTRIBUTE_HANDLER_CLASS);
+
+        // nested list elements rules
+        // Create a list handler, and add it to parent list
+        digester.addObjectCreate(NESTED_LIST, LIST_HANDLER_CLASS);
+        digester.addSetProperties(NESTED_LIST);
+        digester.addSetNext(NESTED_LIST, "add", PUT_ATTRIBUTE_HANDLER_CLASS);
+    }
+
+    /**
+     * Adds a new <code>Definition</code> to the internal Map or replaces
+     * an existing one.
+     *
+     * @param definition The Definition object to be added.
+     */
+    public void addDefinition(Definition definition) {
+        String name = definition.getName();
+        if (name == null) {
+            throw new DigesterDefinitionsReaderException(
+                    "A root definition has been defined with no name");
+        }
+
+        definitions.put(name, definition);
+    }
+
+    /**
+     * Error Handler that throws every exception it receives.
+     */
+    private static class ThrowingErrorHandler implements ErrorHandler {
+
+        /** {@inheritDoc} */
+        public void warning(SAXParseException exception) throws SAXException {
+            throw exception;
+        }
+
+        /** {@inheritDoc} */
+        public void error(SAXParseException exception) throws SAXException {
+            throw exception;
+        }
+
+        /** {@inheritDoc} */
+        public void fatalError(SAXParseException exception) throws SAXException {
+            throw exception;
+        }
+    }
+
+    /**
+     * Returns the registrations for local DTDs.
+     *
+     * @return An array containing the locations for registrations of local
+     * DTDs.
+     * @since 2.1.0
+     */
+    protected String[] getRegistrations() {
+        if (registrations == null) {
+            registrations = new String[] {
+                "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN",
+                "/org/apache/tiles/resources/tiles-config_3_0.dtd"};
+        }
+        return registrations;
+    }
+
+    /**
+     * Create a unique definition name usable to store anonymous definitions.
+     *
+     * @param definitions The already created definitions.
+     * @return The unique definition name to be used to store the definition.
+     * @since 2.1.0
+     */
+    protected String getNextUniqueDefinitionName(
+            Map<String, Definition> definitions) {
+        String candidate;
+
+        do {
+            candidate = "$anonymousDefinition" + anonymousDefinitionIndex;
+            anonymousDefinitionIndex++;
+        } while (definitions.containsKey(candidate));
+
+        return candidate;
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/digester/DigesterDefinitionsReaderException.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/digester/DigesterDefinitionsReaderException.java
new file mode 100644
index 000000000..644f38a5d
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/digester/DigesterDefinitionsReaderException.java
@@ -0,0 +1,73 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.definition.digester;
+
+import org.apache.tiles.TilesException;
+
+/**
+ * Indicates that something went wrong during the use of
+ * {@link DigesterDefinitionsReader}.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.1.0
+ */
+public class DigesterDefinitionsReaderException extends TilesException {
+
+    /**
+     * Constructor.
+     *
+     * @since 2.1.0
+     */
+    public DigesterDefinitionsReaderException() {
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param message The detail message.
+     * @since 2.1.0
+     */
+    public DigesterDefinitionsReaderException(String message) {
+        super(message);
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param e The exception to be wrapped.
+     * @since 2.1.0
+     */
+    public DigesterDefinitionsReaderException(Throwable e) {
+        super(e);
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param message The detail message.
+     * @param e The exception to be wrapped.
+     * @since 2.1.0
+     */
+    public DigesterDefinitionsReaderException(String message, Throwable e) {
+        super(message, e);
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/digester/package-info.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/digester/package-info.java
new file mode 100644
index 000000000..129c2d34a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/digester/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * Allows reading definitions with the use of Jakarta Commons Digester.
+ */
+package org.apache.tiles.definition.digester;
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/package-info.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/package-info.java
new file mode 100644
index 000000000..3e154ecc7
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/package-info.java
@@ -0,0 +1,25 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * It contains classes and interfaces to allow manipulations of "definitions", i.e.
+ * objects made of a template page and a number of filled attributes.
+ */
+package org.apache.tiles.definition;
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/AbstractPatternDefinitionResolver.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/AbstractPatternDefinitionResolver.java
new file mode 100644
index 000000000..137e4b164
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/AbstractPatternDefinitionResolver.java
@@ -0,0 +1,122 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition.pattern;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tiles.Definition;
+
+/**
+ * A pattern definition resolver that stores {@link DefinitionPatternMatcher}
+ * separated by customization key. <br>
+ * Implementations should provide a way to translate a definition to a
+ * {@link DefinitionPatternMatcher}.
+ *
+ * @param <T> The type of the customization key.
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public abstract class AbstractPatternDefinitionResolver<T> implements
+        PatternDefinitionResolver<T> {
+
+    /**
+     * Stores patterns depending on the locale they refer to.
+     */
+    private Map<T, List<DefinitionPatternMatcher>> localePatternPaths =
+        new HashMap<T, List<DefinitionPatternMatcher>>();
+
+    /** {@inheritDoc} */
+    public Definition resolveDefinition(String name, T customizationKey) {
+        Definition retValue = null;
+        if (localePatternPaths.containsKey(customizationKey)) {
+            retValue = searchAndResolveDefinition(localePatternPaths
+                    .get(customizationKey), name);
+        }
+        return retValue;
+    }
+
+    /** {@inheritDoc} */
+    public Map<String, Definition> storeDefinitionPatterns(Map<String, Definition> localeDefsMap,
+            T customizationKey) {
+        List<DefinitionPatternMatcher> lpaths = localePatternPaths
+                .get(customizationKey);
+        if (lpaths == null) {
+            lpaths = new ArrayList<DefinitionPatternMatcher>();
+            localePatternPaths.put(customizationKey, lpaths);
+        }
+
+        return addDefinitionsAsPatternMatchers(lpaths, localeDefsMap);
+    }
+
+    /**
+     * Adds definitions, filtering and adding them to the list of definition
+     * pattern matchers. Only a subset of definitions will be transformed into
+     * definition pattern matchers.
+     *
+     * @param matchers The list containing the currently stored definition pattern
+     * matchers.
+     * @param defsMap The definition map to parse.
+     * @return The map of the definitions not recognized as containing
+     * definition patterns.
+     * @since 2.2.1
+     */
+    protected abstract Map<String, Definition> addDefinitionsAsPatternMatchers(
+            List<DefinitionPatternMatcher> matchers,
+            Map<String, Definition> defsMap);
+
+    /**
+     * Try to resolve a definition by iterating all pattern matchers.
+     *
+     * @param paths The list containing the currently stored paths.
+     * @param name The name of the definition to resolve.
+     * @return A definition, if found, or <code>null</code> if not.
+     */
+    private Definition searchAndResolveDefinition(
+            List<DefinitionPatternMatcher> paths, String name) {
+        Definition d = null;
+
+        for (DefinitionPatternMatcher wm : paths) {
+            d = wm.createDefinition(name);
+            if (d != null) {
+                break;
+            }
+        }
+
+        return d;
+    }
+
+
+    /**
+     * Used to clear all entries in the localePatternPaths for a specific locale. Necessary when reloading definition
+     * files to ensure that the list is cleared first
+     *
+     * @param customizationKey
+     */
+    @Override
+    public void clearPatternPaths(T customizationKey) {
+        if (localePatternPaths.get(customizationKey) != null)
+            localePatternPaths.get(customizationKey).clear();
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/BasicPatternDefinitionResolver.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/BasicPatternDefinitionResolver.java
new file mode 100644
index 000000000..9f6bf4ea4
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/BasicPatternDefinitionResolver.java
@@ -0,0 +1,83 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition.pattern;
+
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.tiles.Definition;
+
+/**
+ * A pattern definition resolver that stores {@link DefinitionPatternMatcher}
+ * separated by customization key. <br>
+ * It delegates creation of definition pattern matchers to a
+ * {@link DefinitionPatternMatcherFactory} and recgnizes patterns through the
+ * use of a {@link PatternRecognizer}.
+ *
+ * @param <T> The type of the customization key.
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public class BasicPatternDefinitionResolver<T> extends
+        AbstractPatternDefinitionResolver<T> {
+
+    /**
+     * The factory of pattern matchers.
+     */
+    private DefinitionPatternMatcherFactory definitionPatternMatcherFactory;
+
+    /**
+     * The pattern recognizer.
+     */
+    private PatternRecognizer patternRecognizer;
+
+    /**
+     * Constructor.
+     *
+     * @param definitionPatternMatcherFactory The definition pattern matcher factory.
+     * @param patternRecognizer The pattern recognizer.
+     */
+    public BasicPatternDefinitionResolver(DefinitionPatternMatcherFactory definitionPatternMatcherFactory,
+            PatternRecognizer patternRecognizer) {
+        this.definitionPatternMatcherFactory = definitionPatternMatcherFactory;
+        this.patternRecognizer = patternRecognizer;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected Map<String, Definition> addDefinitionsAsPatternMatchers(List<DefinitionPatternMatcher> matchers,
+            Map<String, Definition> defsMap) {
+        Set<String> excludedKeys = new LinkedHashSet<String>();
+        for (Map.Entry<String, Definition> de : defsMap.entrySet()) {
+            String key = de.getKey();
+            if (patternRecognizer.isPatternRecognized(key)) {
+                matchers.add(definitionPatternMatcherFactory
+                        .createDefinitionPatternMatcher(key, de.getValue()));
+            } else {
+                excludedKeys.add(key);
+            }
+        }
+        return PatternUtil.createExtractedMap(defsMap, excludedKeys);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/DefinitionPatternMatcher.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/DefinitionPatternMatcher.java
new file mode 100644
index 000000000..e003acc10
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/DefinitionPatternMatcher.java
@@ -0,0 +1,45 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition.pattern;
+
+import org.apache.tiles.Definition;
+
+/**
+ * Matches a definition name to a definition, through pattern-matching. The
+ * matched pattern should be a single one.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public interface DefinitionPatternMatcher {
+
+    /**
+     * Creates a definition, given the definition name, through the use of
+     * pattern matching.
+     *
+     * @param definitionName The definition name to match.
+     * @return The created definition, if matched, or <code>null</code> if not
+     * matched.
+     * @since 2.2.0
+     */
+    Definition createDefinition(String definitionName);
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/DefinitionPatternMatcherFactory.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/DefinitionPatternMatcherFactory.java
new file mode 100644
index 000000000..64a0deb5d
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/DefinitionPatternMatcherFactory.java
@@ -0,0 +1,47 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition.pattern;
+
+import org.apache.tiles.Definition;
+
+/**
+ * Creates a new definition pattern matcher for the given pattern and the given
+ * base definition with pattern expressions.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public interface DefinitionPatternMatcherFactory {
+
+    /**
+     * Creates a new definition pattern matcher.
+     *
+     * @param pattern The pattern to be matched.
+     * @param definition The base definition. Created definitions by
+     * {@link DefinitionPatternMatcher#createDefinition(String)} will created
+     * with this one as a basis.
+     * @return The definition pattern matcher.
+     * @since 2.2.0
+     */
+    DefinitionPatternMatcher createDefinitionPatternMatcher(String pattern,
+            Definition definition);
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/PatternDefinitionResolver.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/PatternDefinitionResolver.java
new file mode 100644
index 000000000..3d24f2f4a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/PatternDefinitionResolver.java
@@ -0,0 +1,68 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition.pattern;
+
+import java.util.Map;
+
+import org.apache.tiles.Definition;
+
+/**
+ * Resolves a definition starting from patterns stored in definition maps.
+ *
+ * @param <T> The type of the customization key.
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public interface PatternDefinitionResolver<T> {
+
+    /**
+     * Stores definition patterns.
+     *
+     * @param localeDefsMap The map of definitions that may contain also
+     * patterns.
+     * @param customizationKey The customization key.
+     * @return The map of the definitions not recognized as containing
+     * definition patterns.
+     * @since 2.2.1
+     */
+    Map<String, Definition> storeDefinitionPatterns(Map<String, Definition> localeDefsMap,
+            T customizationKey);
+
+    /**
+     * Resolves a definition searching in all patterns for the requested
+     * customization key.
+     *
+     * @param name The name of the definition.
+     * @param customizationKey The customization key.
+     * @return The resolved definition.
+     * @since 2.2.0
+     */
+    Definition resolveDefinition(String name, T customizationKey);
+
+    /**
+     * Used to clear all entries in the localePatternPaths for a specific locale. Necessary when reloading definition
+     * files to ensure that the list is cleared first
+     *
+     * @param customizationKey
+     */
+    public void clearPatternPaths(T customizationKey);
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/PatternDefinitionResolverAware.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/PatternDefinitionResolverAware.java
new file mode 100644
index 000000000..b353b34c4
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/PatternDefinitionResolverAware.java
@@ -0,0 +1,40 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition.pattern;
+
+/**
+ * It indicates an object that uses a {@link PatternDefinitionResolver}.
+ *
+ * @param <T> The type of the customization key.
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public interface PatternDefinitionResolverAware<T> {
+
+    /**
+     * Sets the pattern definition resolver to use.
+     *
+     * @param definitionResolver The pattern definition resolver.
+     * @since 2.2.0
+     */
+    void setPatternDefinitionResolver(PatternDefinitionResolver<T> definitionResolver);
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/PatternRecognizer.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/PatternRecognizer.java
new file mode 100644
index 000000000..052fb03a7
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/PatternRecognizer.java
@@ -0,0 +1,40 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition.pattern;
+
+/**
+ * Checks if a pattern (or a candidate one) is recognized as a pattern.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public interface PatternRecognizer {
+
+    /**
+     * Checks if a pattern is recognized as a pattern.
+     *
+     * @param candidatePattern The pattern to check.
+     * @return <code>true</code> if the pattern has been recognized.
+     * @since 2.2.0
+     */
+    boolean isPatternRecognized(String candidatePattern);
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/PatternUtil.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/PatternUtil.java
new file mode 100644
index 000000000..944489718
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/PatternUtil.java
@@ -0,0 +1,243 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition.pattern;
+
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.Definition;
+import org.apache.tiles.Expression;
+import org.apache.tiles.ListAttribute;
+
+/**
+ * Utilities for pattern matching and substitution.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public final class PatternUtil {
+
+    /**
+     * The root locale. Notice that this is a replacement for Locale.ROOT for
+     * Java 1.6.
+     */
+    private static final Locale ROOT_LOCALE = new Locale("", "");
+
+    /** Pattern to find {.*} occurrences that do not match {[0-9]+} so to prevent MessageFormat from crashing.
+     */
+    private static final Pattern INVALID_FORMAT_ELEMENT = Pattern.compile("\\{[^}0-9]+\\}");
+
+    /**
+     * Private constructor to avoid instantiation.
+     */
+    private PatternUtil() {
+    }
+
+    /**
+     * Creates a definition given its representation with wildcards and
+     * attribute values with placeholders, replacing real values into
+     * placeholders.
+     *
+     * @param d The definition to replace.
+     * @param name The name of the definition to be created.
+     * @param varsOrig The variables to be substituted.
+     * @return The definition that can be rendered.
+     * @since 2.2.0
+     */
+    public static Definition replacePlaceholders(Definition d, String name,
+            Object... varsOrig) {
+
+        Object[] vars = replaceNullsWithBlank(varsOrig);
+
+        Definition nudef = new Definition();
+
+        nudef.setExtends(replace(d.getExtends(), vars));
+        nudef.setName(name);
+        nudef.setPreparer(replace(d.getPreparer(), vars));
+        Attribute templateAttribute = d.getTemplateAttribute();
+        if (templateAttribute != null) {
+            nudef.setTemplateAttribute(replaceVarsInAttribute(
+                    templateAttribute, vars));
+        }
+
+        Set<String> attributeNames = d.getLocalAttributeNames();
+        if (attributeNames != null && !attributeNames.isEmpty()) {
+            for (String attributeName : attributeNames) {
+                Attribute attr = d.getLocalAttribute(attributeName);
+                Attribute nuattr = replaceVarsInAttribute(attr, vars);
+
+                nudef.putAttribute(replace(attributeName, vars), nuattr);
+            }
+        }
+
+        attributeNames = d.getCascadedAttributeNames();
+        if (attributeNames != null && !attributeNames.isEmpty()) {
+            for (String attributeName : attributeNames) {
+                Attribute attr = d.getCascadedAttribute(attributeName);
+                Attribute nuattr = replaceVarsInAttribute(attr, vars);
+
+                nudef.putAttribute(replace(attributeName, vars), nuattr, true);
+            }
+        }
+
+        return nudef;
+    }
+
+    /**
+     * Creates a new map that contains all the entries of the
+     * <code>defsMap</code> whose keys are contained in <code>keys</code>.
+     *
+     * @param map The map to read.
+     * @param keys The keys to extract.
+     * @param <K> The key of the map.
+     * @param <V> The value of the map.
+     * @return The extracted map.
+     * @since 2.2.1
+     */
+    public static <K, V> Map<K, V> createExtractedMap(Map<K, V> map, Set<K> keys) {
+        Map<K, V> retValue = new LinkedHashMap<K, V>();
+        for (K key : keys) {
+            retValue.put(key, map.get(key));
+        }
+        return retValue;
+    }
+
+    /**
+     * Replaces variables into an attribute.
+     *
+     * @param attr The attribute to be used as a basis, containing placeholders
+     * for variables.
+     * @param vars The variables to replace.
+     * @return A new instance of an attribute, whose properties have been
+     * replaced with variables' values.
+     */
+    private static Attribute replaceVarsInAttribute(Attribute attr,
+            Object... vars) {
+        Attribute nuattr;
+        if (attr instanceof ListAttribute) {
+            nuattr = replaceVarsInListAttribute((ListAttribute) attr, vars);
+        } else {
+            nuattr = replaceVarsInSimpleAttribute(attr, vars);
+        }
+        return nuattr;
+    }
+
+    /**
+     * Replaces variables into a simple (not list) attribute.
+     *
+     * @param attr The attribute to be used as a basis, containing placeholders
+     * for variables.
+     * @param vars The variables to replace.
+     * @return A new instance of an attribute, whose properties have been
+     * replaced with variables' values.
+     */
+    private static Attribute replaceVarsInSimpleAttribute(Attribute attr,
+            Object... vars) {
+        Attribute nuattr;
+        nuattr = new Attribute();
+
+        nuattr.setRole(replace(attr.getRole(), vars));
+        nuattr.setRenderer(attr.getRenderer());
+        Expression expressionObject = attr.getExpressionObject();
+        if (expressionObject != null) {
+            Expression newExpressionObject = Expression
+                    .createExpression(replace(expressionObject.getExpression(), vars), expressionObject.getLanguage());
+            nuattr.setExpressionObject(newExpressionObject);
+        }
+
+        Object value = attr.getValue();
+        if (value instanceof String) {
+            value = replace((String) value, vars);
+        }
+        nuattr.setValue(value);
+        return nuattr;
+    }
+
+    /**
+     * Replaces variables into a list attribute.
+     *
+     * @param listAttr The attribute to be used as a basis, containing attributes
+     * that may contain placeholders for variables.
+     * @param vars The variables to replace.
+     * @return A new instance of an attribute, whose properties have been
+     * replaced with variables' values.
+     */
+    private static Attribute replaceVarsInListAttribute(ListAttribute listAttr,
+            Object... vars) {
+        Attribute nuattr;
+        ListAttribute nuListAttr = new ListAttribute();
+        nuListAttr.setInherit(listAttr.isInherit());
+        List<Attribute> nuItems = nuListAttr.getValue();
+        for (Object item : listAttr.getValue()) {
+            Attribute child = (Attribute) item;
+            child = replaceVarsInAttribute(child, vars);
+            nuItems.add(child);
+        }
+        nuattr = nuListAttr;
+        return nuattr;
+    }
+
+    /**
+     * Replaces a string with placeholders using values of a variable map.
+     *
+     * @param st The string to replace.
+     * @param vars The variables.
+     * @return The replaced string.
+     */
+    private static String replace(String st, Object... vars) {
+        if (st != null && st.indexOf('{') >= 0) {
+
+            // replace them with markers
+            List<String> originals = new ArrayList<String>();
+            for(Matcher m = INVALID_FORMAT_ELEMENT.matcher(st); m.find() ; m = INVALID_FORMAT_ELEMENT.matcher(st)) {
+                originals.add(m.group());
+                st = m.replaceFirst("INVALID_FORMAT_ELEMENT");
+            }
+
+            // do the MessageFormat replacement (escaping quote characters)
+            st = new MessageFormat(st.replaceAll("'", "'''"), ROOT_LOCALE)
+                    .format(vars, new StringBuffer(), null).toString();
+
+            // return the markers to their original invalid occurrences
+            for (String original : originals) {
+                st = st.replaceFirst("INVALID_FORMAT_ELEMENT", original);
+            }
+        }
+        return st;
+    }
+
+    private static Object[] replaceNullsWithBlank(Object[] varsOrig) {
+        Object[] vars = new Object[varsOrig.length];
+        for(int i = 0; i < varsOrig.length; ++i) {
+            vars[i] = null != varsOrig[i] ? varsOrig[i] : "";
+        }
+        return vars;
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/PrefixedPatternDefinitionResolver.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/PrefixedPatternDefinitionResolver.java
new file mode 100644
index 000000000..e5a391241
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/PrefixedPatternDefinitionResolver.java
@@ -0,0 +1,111 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition.pattern;
+
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.tiles.Definition;
+import org.apache.tiles.Expression;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This resolver allows the use of multiple pattern matching languages. The
+ * syntax of definition names must be <code>LANGUAGENAME:expression</code>.<br>
+ * The different languages must be registered through the use of
+ * {@link #registerDefinitionPatternMatcherFactory(String, DefinitionPatternMatcherFactory)}
+ * method before using this resolver.
+ *
+ * @param <T> The type of the customization key.
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public class PrefixedPatternDefinitionResolver<T> extends
+        AbstractPatternDefinitionResolver<T> {
+
+    /**
+     * The logging object.
+     */
+    private Logger logger = LoggerFactory.getLogger(getClass());
+
+    /**
+     * Matches languages names to the corresponding
+     * {@link DefinitionPatternMatcherFactory}.
+     */
+    private Map<String, DefinitionPatternMatcherFactory> language2matcherFactory;
+
+    /**
+     * Constructor.
+     *
+     * @since 2.2.0
+     */
+    public PrefixedPatternDefinitionResolver() {
+        language2matcherFactory = new HashMap<String, DefinitionPatternMatcherFactory>();
+    }
+
+    /**
+     * Registers a {@link DefinitionPatternMatcherFactory} connected to a
+     * particular language.
+     *
+     * @param language The name of the language.
+     * @param factory The pattern matcher factory to register.
+     * @since 2.2.0
+     */
+    public void registerDefinitionPatternMatcherFactory(String language,
+            DefinitionPatternMatcherFactory factory) {
+        language2matcherFactory.put(language, factory);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected Map<String, Definition> addDefinitionsAsPatternMatchers(
+            List<DefinitionPatternMatcher> matchers,
+            Map<String, Definition> defsMap) {
+        Set<String> excludedKeys = new LinkedHashSet<String>();
+        for (Map.Entry<String, Definition> entry : defsMap.entrySet()) {
+            String key = entry.getKey();
+            Expression expression = Expression
+                    .createExpressionFromDescribedExpression(key);
+            if (expression.getLanguage() != null) {
+                DefinitionPatternMatcherFactory factory = language2matcherFactory
+                        .get(expression.getLanguage());
+                if (factory != null) {
+                    DefinitionPatternMatcher matcher = factory
+                            .createDefinitionPatternMatcher(expression
+                                    .getExpression(), new Definition(entry
+                                    .getValue()));
+                    matchers.add(matcher);
+                } else {
+                    logger.warn("Cannot find a DefinitionPatternMatcherFactory for expression '{}'",
+                            key);
+                }
+            } else {
+                excludedKeys.add(key);
+            }
+        }
+        return PatternUtil.createExtractedMap(defsMap, excludedKeys);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/package-info.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/package-info.java
new file mode 100644
index 000000000..e41a60d88
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * Classes to manage pattern matching in definition names, and substitution in attributes.
+ */
+package org.apache.tiles.definition.pattern;
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/regexp/RegexpDefinitionPatternMatcher.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/regexp/RegexpDefinitionPatternMatcher.java
new file mode 100644
index 000000000..6442d3374
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/regexp/RegexpDefinitionPatternMatcher.java
@@ -0,0 +1,76 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition.pattern.regexp;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.tiles.Definition;
+import org.apache.tiles.definition.pattern.DefinitionPatternMatcher;
+import org.apache.tiles.definition.pattern.PatternUtil;
+
+/**
+ * Matches regular expression patterns in definitions.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public class RegexpDefinitionPatternMatcher implements DefinitionPatternMatcher {
+
+    /**
+     * The pattern to match.
+     */
+    private Pattern pattern;
+
+    /**
+     * The definition to use as a basis.
+     */
+    private Definition definition;
+
+    /**
+     * Constructor.
+     *
+     * @param pattern The pattern to use, in string form.
+     * @param definition The definition to use as a basis.
+     * @since 2.2.0
+     */
+    public RegexpDefinitionPatternMatcher(String pattern, Definition definition) {
+        this.pattern = Pattern.compile(pattern);
+        this.definition = definition;
+    }
+
+    /** {@inheritDoc} */
+    public Definition createDefinition(String definitionName) {
+        Definition retValue = null;
+        Matcher matcher = pattern.matcher(definitionName);
+        if (matcher.matches()) {
+            int groupCount = matcher.groupCount() + 1;
+            Object[] vars = new Object[groupCount];
+            for (int i = 0; i < groupCount; i++) {
+                vars[i] = matcher.group(i);
+            }
+            retValue = PatternUtil.replacePlaceholders(definition,
+                    definitionName, vars);
+        }
+        return retValue;
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/regexp/RegexpDefinitionPatternMatcherFactory.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/regexp/RegexpDefinitionPatternMatcherFactory.java
new file mode 100644
index 000000000..2c1700694
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/regexp/RegexpDefinitionPatternMatcherFactory.java
@@ -0,0 +1,41 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition.pattern.regexp;
+
+import org.apache.tiles.Definition;
+import org.apache.tiles.definition.pattern.DefinitionPatternMatcher;
+import org.apache.tiles.definition.pattern.DefinitionPatternMatcherFactory;
+
+/**
+ * Creates instances of {@link RegexpDefinitionPatternMatcher}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class RegexpDefinitionPatternMatcherFactory implements
+        DefinitionPatternMatcherFactory {
+
+    /** {@inheritDoc} */
+    public DefinitionPatternMatcher createDefinitionPatternMatcher(
+            String pattern, Definition definition) {
+        return new RegexpDefinitionPatternMatcher(pattern, definition);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/regexp/package-info.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/regexp/package-info.java
new file mode 100644
index 000000000..f1fce91b2
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/regexp/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * In Tiles it is possible to use regular expression patterns thanks to this package.
+ */
+package org.apache.tiles.definition.pattern.regexp;
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/wildcard/WildcardDefinitionPatternMatcher.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/wildcard/WildcardDefinitionPatternMatcher.java
new file mode 100644
index 000000000..033cd6ad3
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/wildcard/WildcardDefinitionPatternMatcher.java
@@ -0,0 +1,84 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition.pattern.wildcard;
+
+import java.util.List;
+
+import org.apache.tiles.Definition;
+import org.apache.tiles.definition.pattern.DefinitionPatternMatcher;
+import org.apache.tiles.definition.pattern.PatternUtil;
+import org.apache.tiles.util.WildcardHelper;
+
+/**
+ * Matches wildcard patterns in definitions.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public class WildcardDefinitionPatternMatcher implements
+        DefinitionPatternMatcher {
+
+    /**
+     * Allows to parse wildcard expressions and to recognize substitution
+     * variables.
+     */
+    private WildcardHelper wildcardHelper;
+
+    /**
+     * The definition to use as a basis.
+     */
+    private Definition definition;
+
+    /**
+     * The pattern to use.
+     */
+    private int[] pattern;
+
+    /**
+     * Constructor.
+     *
+     * @param pattern The pattern to use, in string form.
+     * @param definition The definition to use as a basis.
+     * @param wildcardHelper The object that parses wildcard expressions and
+     * recognized substitution variables.
+     * @since 2.2.0
+     */
+    public WildcardDefinitionPatternMatcher(String pattern,
+            Definition definition, WildcardHelper wildcardHelper) {
+        this.wildcardHelper = wildcardHelper;
+        this.definition = definition;
+        this.pattern = wildcardHelper.compilePattern(pattern);
+    }
+
+    /** {@inheritDoc} */
+    public Definition createDefinition(String definitionName) {
+        List<String> vars = wildcardHelper.match(definitionName, pattern);
+        Definition d = null;
+
+        if (vars != null) {
+            d = PatternUtil.replacePlaceholders(definition, definitionName,
+                    vars.toArray());
+        }
+
+        return d;
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/wildcard/WildcardDefinitionPatternMatcherFactory.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/wildcard/WildcardDefinitionPatternMatcherFactory.java
new file mode 100644
index 000000000..6cb05b5b3
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/wildcard/WildcardDefinitionPatternMatcherFactory.java
@@ -0,0 +1,55 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition.pattern.wildcard;
+
+import org.apache.tiles.Definition;
+import org.apache.tiles.definition.pattern.DefinitionPatternMatcher;
+import org.apache.tiles.definition.pattern.DefinitionPatternMatcherFactory;
+import org.apache.tiles.definition.pattern.PatternRecognizer;
+import org.apache.tiles.util.WildcardHelper;
+
+/**
+ * Creates instances of {@link WildcardDefinitionPatternMatcher}.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public class WildcardDefinitionPatternMatcherFactory implements
+        DefinitionPatternMatcherFactory, PatternRecognizer {
+
+    /**
+     * Allows to parse wildcard expressions and to recognize substitution
+     * variables.
+     */
+    private WildcardHelper wildcardHelper = new WildcardHelper();
+
+    /** {@inheritDoc} */
+    public DefinitionPatternMatcher createDefinitionPatternMatcher(
+            String pattern, Definition definition) {
+        return new WildcardDefinitionPatternMatcher(pattern, definition, wildcardHelper);
+    }
+
+    /** {@inheritDoc} */
+    public boolean isPatternRecognized(String candidatePattern) {
+        return candidatePattern.indexOf('*') >= 0;
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/wildcard/package-info.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/wildcard/package-info.java
new file mode 100644
index 000000000..9de2624c7
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/definition/pattern/wildcard/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * In Tiles it is possible to use wildcard patterns thanks to this package.
+ */
+package org.apache.tiles.definition.pattern.wildcard;
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/doc-files/image001.gif b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/doc-files/image001.gif
new file mode 100644
index 000000000..f675c127c
Binary files /dev/null and b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/doc-files/image001.gif differ
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/evaluator/AbstractAttributeEvaluator.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/evaluator/AbstractAttributeEvaluator.java
new file mode 100644
index 000000000..82542a690
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/evaluator/AbstractAttributeEvaluator.java
@@ -0,0 +1,54 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.evaluator;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.Expression;
+import org.apache.tiles.request.Request;
+
+/**
+ * Abstract class to link a correct evaluation of an attribute, by evaluating
+ * {@link Attribute#getValue()} and then {@link Attribute#getExpressionObject()}.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.1.2
+ */
+public abstract class AbstractAttributeEvaluator implements AttributeEvaluator {
+
+    /** {@inheritDoc} */
+    public Object evaluate(Attribute attribute, Request request) {
+        if (attribute == null) {
+            throw new IllegalArgumentException("The attribute cannot be null");
+        }
+
+        Object retValue = attribute.getValue();
+
+        if (retValue == null) {
+            Expression expression = attribute.getExpressionObject();
+            if (expression != null) {
+                retValue = evaluate(attribute.getExpressionObject()
+                        .getExpression(), request);
+            }
+        }
+
+        return retValue;
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/evaluator/AttributeEvaluator.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/evaluator/AttributeEvaluator.java
new file mode 100644
index 000000000..ae5839a76
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/evaluator/AttributeEvaluator.java
@@ -0,0 +1,53 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.evaluator;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.request.Request;
+
+/**
+ * It represents an object that resolves a string to return an object.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.1.0
+ */
+public interface AttributeEvaluator {
+
+    /**
+     * Evaluates an expression.
+     *
+     * @param expression The expression to evaluate.
+     * @param request The request object.
+     * @return The evaluated object.
+     * @since 2.1.0
+     */
+    Object evaluate(String expression, Request request);
+
+    /**
+     * Evaluates an attribute value.
+     *
+     * @param attribute The attribute to evaluate.
+     * @param request The request object.
+     * @return The evaluated object.
+     * @since 2.1.0
+     */
+    Object evaluate(Attribute attribute, Request request);
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/evaluator/AttributeEvaluatorFactory.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/evaluator/AttributeEvaluatorFactory.java
new file mode 100644
index 000000000..ae77f088a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/evaluator/AttributeEvaluatorFactory.java
@@ -0,0 +1,51 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.evaluator;
+
+import org.apache.tiles.Attribute;
+
+/**
+ * Creates an attribute evaluator using the language or an attribute.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public interface AttributeEvaluatorFactory {
+
+    /**
+     * Creates and attribute evaluator using an attribute.
+     *
+     * @param attribute The attribute used to obtain the evaluator.
+     * @return The attribute evaluator. It must not be <code>null</code>.
+     * @since 2.2.0
+     */
+    AttributeEvaluator getAttributeEvaluator(Attribute attribute);
+
+    /**
+     * Creates and attribute evaluator for the given expression language.
+     *
+     * @param language The name of the expression language.
+     * @return The attribute evaluator. It must not be <code>null</code>.
+     * @since 2.2.0
+     */
+    AttributeEvaluator getAttributeEvaluator(String language);
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/evaluator/AttributeEvaluatorFactoryAware.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/evaluator/AttributeEvaluatorFactoryAware.java
new file mode 100644
index 000000000..9f5671640
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/evaluator/AttributeEvaluatorFactoryAware.java
@@ -0,0 +1,39 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.evaluator;
+
+/**
+ * It represents an object that can use an {@link AttributeEvaluatorFactory}.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public interface AttributeEvaluatorFactoryAware {
+
+    /**
+     * Sets the attribute evaluator factory.
+     *
+     * @param attributeEvaluatorFactory The attribute evaluator factory to use.
+     * @since 2.2.0
+     */
+    void setAttributeEvaluatorFactory(AttributeEvaluatorFactory attributeEvaluatorFactory);
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/evaluator/BasicAttributeEvaluatorFactory.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/evaluator/BasicAttributeEvaluatorFactory.java
new file mode 100644
index 000000000..c4c396b21
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/evaluator/BasicAttributeEvaluatorFactory.java
@@ -0,0 +1,93 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.evaluator;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.Expression;
+
+/**
+ * Basic implementation of {@link AttributeEvaluatorFactory}. It supports a
+ * default attribute evaluator, in case the language is not recognized.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public class BasicAttributeEvaluatorFactory implements
+        AttributeEvaluatorFactory {
+
+    /**
+     * The default evaluator to return if it is not found in the map of known
+     * languages.
+     */
+    private AttributeEvaluator defaultEvaluator;
+
+    /**
+     * Maps names of expression languages to their attribute evaluator.
+     *
+     * @since 2.2.0
+     */
+    private Map<String, AttributeEvaluator> language2evaluator;
+
+    /**
+     * Constructor.
+     *
+     * @param defaultEvaluator The default evaluator to return if it is not
+     * found in the map of known languages.
+     * @since 2.2.0
+     */
+    public BasicAttributeEvaluatorFactory(AttributeEvaluator defaultEvaluator) {
+        this.defaultEvaluator = defaultEvaluator;
+        language2evaluator = new HashMap<String, AttributeEvaluator>();
+    }
+
+    /**
+     * Registers a known expression language with its attribute evaluator.
+     *
+     * @param language The name of the expression language.
+     * @param evaluator The associated attribute evaluator.
+     * @since 2.2.0
+     */
+    public void registerAttributeEvaluator(String language, AttributeEvaluator evaluator) {
+        language2evaluator.put(language, evaluator);
+    }
+
+    /** {@inheritDoc} */
+    public AttributeEvaluator getAttributeEvaluator(String language) {
+        AttributeEvaluator retValue = language2evaluator.get(language);
+        if (retValue == null) {
+            retValue = defaultEvaluator;
+        }
+        return retValue;
+    }
+
+    /** {@inheritDoc} */
+    public AttributeEvaluator getAttributeEvaluator(Attribute attribute) {
+        Expression expression = attribute.getExpressionObject();
+        if (expression != null) {
+            return getAttributeEvaluator(expression.getLanguage());
+        }
+        return defaultEvaluator;
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/evaluator/EvaluationException.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/evaluator/EvaluationException.java
new file mode 100644
index 000000000..2b05ca3d4
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/evaluator/EvaluationException.java
@@ -0,0 +1,72 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.evaluator;
+
+import org.apache.tiles.TilesException;
+
+/**
+ * Exception raised when an expression language evaluation fails.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public class EvaluationException extends TilesException {
+
+    /**
+     * Constructor.
+     *
+     * @since 2.2.0
+     */
+    public EvaluationException() {
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param message The message-
+     * @since 2.2.0
+     */
+    public EvaluationException(String message) {
+        super(message);
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param e The cause.
+     * @since 2.2.0
+     */
+    public EvaluationException(Throwable e) {
+        super(e);
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param message The message-
+     * @param e The cause.
+     * @since 2.2.0
+     */
+    public EvaluationException(String message, Throwable e) {
+        super(message, e);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/evaluator/impl/DirectAttributeEvaluator.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/evaluator/impl/DirectAttributeEvaluator.java
new file mode 100644
index 000000000..6a9d0f4e0
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/evaluator/impl/DirectAttributeEvaluator.java
@@ -0,0 +1,39 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.evaluator.impl;
+
+import org.apache.tiles.evaluator.AbstractAttributeEvaluator;
+import org.apache.tiles.request.Request;
+
+/**
+ * Resolves a string and returns the string itself. It is useful for backward
+ * compatibility.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.1.0
+ */
+public class DirectAttributeEvaluator extends AbstractAttributeEvaluator {
+
+    /** {@inheritDoc} */
+    public Object evaluate(String expression, Request request) {
+        return expression;
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/evaluator/impl/package-info.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/evaluator/impl/package-info.java
new file mode 100644
index 000000000..de8854209
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/evaluator/impl/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * Classes to manage attribute value evaluation.
+ */
+package org.apache.tiles.evaluator.impl;
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/evaluator/package-info.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/evaluator/package-info.java
new file mode 100644
index 000000000..6ba1ab1a8
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/evaluator/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * Interfaces to manage attribute value evaluation.
+ */
+package org.apache.tiles.evaluator;
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/factory/AbstractTilesContainerFactory.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/factory/AbstractTilesContainerFactory.java
new file mode 100644
index 000000000..9111fc5fd
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/factory/AbstractTilesContainerFactory.java
@@ -0,0 +1,53 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.factory;
+
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.request.ApplicationContext;
+
+/**
+ * Abstract Factory that creates instances of {@link TilesContainerFactory}.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.1.0
+ */
+public abstract class AbstractTilesContainerFactory {
+
+    /**
+     * Initialization parameter that represents the container factory class
+     * name.
+     *
+     * @since 2.1.0
+     */
+    public static final String CONTAINER_FACTORY_INIT_PARAM =
+        "org.apache.tiles.factory.AbstractTilesContainerFactory";
+
+    /**
+     * Creates a Tiles container.
+     *
+     * @param applicationContext The Tiles application context object.
+     * @return The created container.
+     * @throws TilesContainerFactoryException If something goes wrong during
+     * instantiation.
+     * @since 2.1.1
+     */
+    public abstract TilesContainer createContainer(ApplicationContext applicationContext);
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/factory/BasicTilesContainerFactory.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/factory/BasicTilesContainerFactory.java
new file mode 100644
index 000000000..2bc10ada6
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/factory/BasicTilesContainerFactory.java
@@ -0,0 +1,400 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.factory;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.definition.DefinitionsFactory;
+import org.apache.tiles.definition.DefinitionsReader;
+import org.apache.tiles.definition.UnresolvingLocaleDefinitionsFactory;
+import org.apache.tiles.definition.dao.BaseLocaleUrlDefinitionDAO;
+import org.apache.tiles.definition.dao.DefinitionDAO;
+import org.apache.tiles.definition.dao.ResolvingLocaleUrlDefinitionDAO;
+import org.apache.tiles.definition.digester.DigesterDefinitionsReader;
+import org.apache.tiles.definition.pattern.BasicPatternDefinitionResolver;
+import org.apache.tiles.definition.pattern.PatternDefinitionResolver;
+import org.apache.tiles.definition.pattern.PatternDefinitionResolverAware;
+import org.apache.tiles.definition.pattern.wildcard.WildcardDefinitionPatternMatcherFactory;
+import org.apache.tiles.evaluator.AttributeEvaluatorFactory;
+import org.apache.tiles.evaluator.BasicAttributeEvaluatorFactory;
+import org.apache.tiles.evaluator.impl.DirectAttributeEvaluator;
+import org.apache.tiles.impl.BasicTilesContainer;
+import org.apache.tiles.locale.LocaleResolver;
+import org.apache.tiles.locale.impl.DefaultLocaleResolver;
+import org.apache.tiles.preparer.factory.BasicPreparerFactory;
+import org.apache.tiles.preparer.factory.PreparerFactory;
+import org.apache.tiles.renderer.DefinitionRenderer;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.ApplicationResource;
+import org.apache.tiles.request.render.BasicRendererFactory;
+import org.apache.tiles.request.render.ChainedDelegateRenderer;
+import org.apache.tiles.request.render.DispatchRenderer;
+import org.apache.tiles.request.render.Renderer;
+import org.apache.tiles.request.render.RendererFactory;
+import org.apache.tiles.request.render.StringRenderer;
+
+/**
+ * Factory that builds a standard Tiles container using only Java code.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.1.0
+ */
+public class BasicTilesContainerFactory extends AbstractTilesContainerFactory {
+
+    /**
+     * The string renderer name.
+     */
+    protected static final String STRING_RENDERER_NAME = "string";
+
+    /**
+     * The template renderer name.
+     */
+    protected static final String TEMPLATE_RENDERER_NAME = "template";
+
+    /**
+     * The definition renderer name.
+     */
+    protected static final String DEFINITION_RENDERER_NAME = "definition";
+
+    /** {@inheritDoc} */
+    @Override
+    public TilesContainer createContainer(ApplicationContext applicationContext) {
+        BasicTilesContainer container = instantiateContainer(applicationContext);
+        container.setApplicationContext(applicationContext);
+        LocaleResolver resolver = createLocaleResolver(applicationContext);
+        container.setDefinitionsFactory(createDefinitionsFactory(applicationContext,
+                resolver));
+        AttributeEvaluatorFactory attributeEvaluatorFactory = createAttributeEvaluatorFactory(
+                applicationContext, resolver);
+        container.setAttributeEvaluatorFactory(attributeEvaluatorFactory);
+        container.setPreparerFactory(createPreparerFactory(applicationContext));
+        TilesContainer injectedContainer = createDecoratedContainer(container, applicationContext);
+        container.setRendererFactory(createRendererFactory(applicationContext,
+                injectedContainer, attributeEvaluatorFactory));
+        return injectedContainer;
+    }
+
+    /**
+     * Instantiate the container, without initialization.
+     *
+     * @param context The Tiles application context object.
+     * @return The instantiated container.
+     * @since 2.1.1
+     */
+    protected BasicTilesContainer instantiateContainer(
+            ApplicationContext context) {
+        return new BasicTilesContainer();
+    }
+
+    /**
+     * Instantiate the container that will be injected to child objects.
+     *
+     * @param originalContainer The original instantiated container.
+     * @param context The Tiles application context object.
+     * @return The instantiated container.
+     * @since 3.0.0
+     */
+    protected TilesContainer createDecoratedContainer(TilesContainer originalContainer,
+            ApplicationContext context) {
+        return originalContainer;
+    }
+
+    /**
+     * Creates the definitions factory. By default it creates a
+     * {@link UnresolvingLocaleDefinitionsFactory} with default dependencies.
+     *
+     * @param applicationContext The Tiles application context.
+     * @param resolver The locale resolver.
+     * @return The definitions factory.
+     * @since 2.1.1
+     */
+    protected DefinitionsFactory createDefinitionsFactory(ApplicationContext applicationContext,
+            LocaleResolver resolver) {
+        UnresolvingLocaleDefinitionsFactory factory = instantiateDefinitionsFactory(
+                applicationContext, resolver);
+        factory.setLocaleResolver(resolver);
+        factory.setDefinitionDAO(createLocaleDefinitionDao(applicationContext,
+                resolver));
+        return factory;
+    }
+
+    /**
+     * Instantiate a new definitions factory based on Locale.
+     * @param applicationContext The Tiles application context.
+     * @param resolver The locale resolver.
+     * @return The definitions factory.
+     * @since 2.2.1
+     */
+    protected UnresolvingLocaleDefinitionsFactory instantiateDefinitionsFactory(
+            ApplicationContext applicationContext,
+            LocaleResolver resolver) {
+        return new UnresolvingLocaleDefinitionsFactory();
+    }
+
+
+    /**
+     * Instantiate (and does not initialize) a Locale-based definition DAO.
+     * @param applicationContext The Tiles application context.
+     * @param resolver The locale resolver.
+     * @return The definition DAO.
+     * @since 2.1.1
+     */
+    protected BaseLocaleUrlDefinitionDAO instantiateLocaleDefinitionDao(ApplicationContext applicationContext,
+            LocaleResolver resolver) {
+        ResolvingLocaleUrlDefinitionDAO dao = new ResolvingLocaleUrlDefinitionDAO(applicationContext);
+        return dao;
+    }
+
+    /**
+     * Creates a Locale-based definition DAO.
+     * @param applicationContext The Tiles application context.
+     * @param resolver The locale resolver.
+     * @return The definition DAO.
+     * @since 2.1.1
+     */
+    @SuppressWarnings("unchecked")
+    protected DefinitionDAO<Locale> createLocaleDefinitionDao(ApplicationContext applicationContext,
+            LocaleResolver resolver) {
+        BaseLocaleUrlDefinitionDAO definitionDao = instantiateLocaleDefinitionDao(
+                applicationContext, resolver);
+        definitionDao.setReader(createDefinitionsReader(applicationContext));
+        definitionDao.setSources(getSources(applicationContext));
+        if (definitionDao instanceof PatternDefinitionResolverAware) {
+            ((PatternDefinitionResolverAware<Locale>) definitionDao)
+                    .setPatternDefinitionResolver(createPatternDefinitionResolver(Locale.class));
+        }
+        return definitionDao;
+    }
+
+    /**
+     * Creates the locale resolver. By default it creates a
+     * {@link DefaultLocaleResolver}.
+     * @param applicationContext The Tiles application context.
+     * @return The locale resolver.
+     * @since 2.1.1
+     */
+    protected LocaleResolver createLocaleResolver(ApplicationContext applicationContext) {
+        return new DefaultLocaleResolver();
+    }
+
+    /**
+     * Creates the definitions reader. By default it creates a
+     * {@link DigesterDefinitionsReader}.
+     * @param applicationContext The Tiles application context.
+     * @return The definitions reader.
+     * @since 2.1.1
+     */
+    protected DefinitionsReader createDefinitionsReader(
+            ApplicationContext applicationContext) {
+        return new DigesterDefinitionsReader();
+    }
+
+    /**
+     * Returns a list containing the resources to be parsed. By default, it returns a
+     * list containing the resource at "/WEB-INF/tiles.xml".
+     * @param applicationContext The Tiles application context.
+     * @return The resources.
+     * @since 2.1.1
+     */
+    protected List<ApplicationResource> getSources(ApplicationContext applicationContext) {
+        List<ApplicationResource> retValue = new ArrayList<ApplicationResource>(1);
+        retValue.add(applicationContext.getResource("/WEB-INF/tiles.xml"));
+        return retValue;
+    }
+
+    /**
+     * Creates the attribute evaluator factory to use. By default it returns a
+     * {@link BasicAttributeEvaluatorFactory} containing the
+     * {@link DirectAttributeEvaluator} as the default evaluator.
+     *
+     * @param applicationContext The Tiles application context.
+     * @param resolver The locale resolver.
+     * @return The evaluator factory.
+     * @since 2.2.0
+     */
+    protected AttributeEvaluatorFactory createAttributeEvaluatorFactory(
+            ApplicationContext applicationContext,
+            LocaleResolver resolver) {
+        return new BasicAttributeEvaluatorFactory(new DirectAttributeEvaluator());
+    }
+
+    /**
+     * Creates the preparer factory to use. By default it returns a
+     * {@link BasicPreparerFactory}.
+     * @param applicationContext The Tiles application context.
+     * @return The preparer factory.
+     * @since 2.1.1
+     */
+    protected PreparerFactory createPreparerFactory(ApplicationContext applicationContext) {
+        return new BasicPreparerFactory();
+    }
+
+    /**
+     * Creates a renderer factory. By default it returns a
+     * {@link BasicRendererFactory}, composed of an
+     * {@link UntypedAttributeRenderer} as default, and delegates of
+     * {@link StringRenderer}, {@link DispatchRenderer},
+     * {@link DefinitionRenderer}.
+     *
+     * @param applicationContext The Tiles application context.
+     * @param container The container.
+     * @param attributeEvaluatorFactory The attribute evaluator factory.
+     * @return The renderer factory.
+     * @since 2.2.0
+     */
+    protected RendererFactory createRendererFactory(ApplicationContext applicationContext,
+            TilesContainer container,
+            AttributeEvaluatorFactory attributeEvaluatorFactory) {
+        BasicRendererFactory retValue = new BasicRendererFactory();
+        registerAttributeRenderers(retValue, applicationContext, container,
+                attributeEvaluatorFactory);
+        retValue.setDefaultRenderer(createDefaultAttributeRenderer(retValue,
+                applicationContext, container, attributeEvaluatorFactory));
+        return retValue;
+    }
+
+    /**
+     * Creates the default attribute renderer. By default it is an
+     * {@link ChainedDelegateRenderer}.
+     *
+     * @param rendererFactory The renderer factory to configure.
+     * @param applicationContext The Tiles application context.
+     * @param container The container.
+     * @param attributeEvaluatorFactory The attribute evaluator factory.
+     * @return The default attribute renderer.
+     * @since 3.0.0
+     */
+    protected Renderer createDefaultAttributeRenderer(
+            BasicRendererFactory rendererFactory,
+            ApplicationContext applicationContext,
+            TilesContainer container,
+            AttributeEvaluatorFactory attributeEvaluatorFactory) {
+        ChainedDelegateRenderer retValue = new ChainedDelegateRenderer();
+        retValue.addAttributeRenderer(rendererFactory.getRenderer(DEFINITION_RENDERER_NAME));
+        retValue.addAttributeRenderer(rendererFactory.getRenderer(TEMPLATE_RENDERER_NAME));
+        retValue.addAttributeRenderer(rendererFactory.getRenderer(STRING_RENDERER_NAME));
+        return retValue;
+    }
+
+    /**
+     * Creates a new pattern definition resolver. By default, it instantiate a
+     * {@link BasicPatternDefinitionResolver} with
+     * {@link WildcardDefinitionPatternMatcherFactory} to manage wildcard
+     * substitution.
+     *
+     * @param <T> The type of the customization key.
+     * @param customizationKeyClass The customization key class.
+     * @return The pattern definition resolver.
+     * @since 2.2.0
+     */
+    protected <T> PatternDefinitionResolver<T> createPatternDefinitionResolver(
+            Class<T> customizationKeyClass) {
+        WildcardDefinitionPatternMatcherFactory definitionPatternMatcherFactory =
+            new WildcardDefinitionPatternMatcherFactory();
+        return new BasicPatternDefinitionResolver<T>(
+                definitionPatternMatcherFactory,
+                definitionPatternMatcherFactory);
+    }
+
+    /**
+     * Registers attribute renderers in a {@link BasicRendererFactory}. By
+     * default, it registers delegates to {@link StringRenderer},
+     * {@link DispatchRenderer} and {@link DefinitionRenderer}.
+     *
+     * @param rendererFactory The renderer factory to configure.
+     * @param applicationContext The Tiles application context.
+     * @param container The container.
+     * @param attributeEvaluatorFactory The attribute evaluator factory.
+     * @since 2.2.0
+     */
+    protected void registerAttributeRenderers(
+            BasicRendererFactory rendererFactory,
+            ApplicationContext applicationContext,
+            TilesContainer container,
+            AttributeEvaluatorFactory attributeEvaluatorFactory) {
+        rendererFactory.registerRenderer(STRING_RENDERER_NAME,
+                createStringAttributeRenderer(rendererFactory,
+                        applicationContext, container, attributeEvaluatorFactory));
+        rendererFactory.registerRenderer(TEMPLATE_RENDERER_NAME,
+                createTemplateAttributeRenderer(rendererFactory,
+                        applicationContext, container, attributeEvaluatorFactory));
+        rendererFactory.registerRenderer(DEFINITION_RENDERER_NAME,
+                createDefinitionAttributeRenderer(rendererFactory,
+                        applicationContext, container, attributeEvaluatorFactory));
+    }
+
+    /**
+     * Creates an attribute renderer to render strings.
+     *
+     * @param rendererFactory The renderer factory to configure.
+     * @param applicationContext The Tiles application context.
+     * @param container The container.
+     * @param attributeEvaluatorFactory The attribute evaluator factory.
+     * @return The renderer.
+     * @since 3.0.0
+     */
+    protected Renderer createStringAttributeRenderer(
+            BasicRendererFactory rendererFactory,
+            ApplicationContext applicationContext,
+            TilesContainer container,
+            AttributeEvaluatorFactory attributeEvaluatorFactory) {
+        return new StringRenderer();
+    }
+
+    /**
+     * Creates a {@link AttributeRenderer} that uses a {@link DispatchRenderer}.
+     *
+     * @param rendererFactory The renderer factory to configure.
+     * @param applicationContext The Tiles application context.
+     * @param container The container.
+     * @param attributeEvaluatorFactory The attribute evaluator factory.
+     * @return The renderer.
+     * @since 2.2.1
+     */
+    protected Renderer createTemplateAttributeRenderer(
+            BasicRendererFactory rendererFactory,
+            ApplicationContext applicationContext,
+            TilesContainer container,
+            AttributeEvaluatorFactory attributeEvaluatorFactory) {
+        return new DispatchRenderer();
+    }
+
+    /**
+     * Creates a {@link AttributeRenderer} using a {@link DefinitionRenderer}.
+     *
+     * @param rendererFactory The renderer factory to configure.
+     * @param applicationContext The Tiles application context.
+     * @param container The container.
+     * @param attributeEvaluatorFactory The attribute evaluator factory.
+     * @return The renderer.
+     * @since 3.0.0
+     */
+    protected Renderer createDefinitionAttributeRenderer(
+            BasicRendererFactory rendererFactory,
+            ApplicationContext applicationContext,
+            TilesContainer container,
+            AttributeEvaluatorFactory attributeEvaluatorFactory) {
+        return new DefinitionRenderer(container);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/factory/TilesContainerFactoryException.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/factory/TilesContainerFactoryException.java
new file mode 100644
index 000000000..18b85953f
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/factory/TilesContainerFactoryException.java
@@ -0,0 +1,72 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.factory;
+
+import org.apache.tiles.TilesException;
+
+/**
+ * Indicates that something went wrong in {@link TilesContainerFactory} use.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.1.0
+ */
+public class TilesContainerFactoryException extends TilesException {
+
+    /**
+     * Constructor.
+     *
+     * @since 2.1.0
+     */
+    public TilesContainerFactoryException() {
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param message The detail message.
+     * @since 2.1.0
+     */
+    public TilesContainerFactoryException(String message) {
+        super(message);
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param e The exception to be wrapped.
+     * @since 2.1.0
+     */
+    public TilesContainerFactoryException(Throwable e) {
+        super(e);
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param message The detail message.
+     * @param e The exception to be wrapped.
+     * @since 2.1.0
+     */
+    public TilesContainerFactoryException(String message, Throwable e) {
+        super(message, e);
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/factory/package-info.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/factory/package-info.java
new file mode 100644
index 000000000..9223e1387
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/factory/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * Factory classes, to allow creation of container instances.
+ */
+package org.apache.tiles.factory;
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/impl/BasicTilesContainer.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/impl/BasicTilesContainer.java
new file mode 100644
index 000000000..05ad174ee
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/impl/BasicTilesContainer.java
@@ -0,0 +1,402 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.impl;
+
+import java.io.IOException;
+import java.util.Deque;
+import java.util.LinkedList;
+import java.util.Map;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.AttributeContext;
+import org.apache.tiles.BasicAttributeContext;
+import org.apache.tiles.Definition;
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.definition.DefinitionsFactory;
+import org.apache.tiles.definition.NoSuchDefinitionException;
+import org.apache.tiles.evaluator.AttributeEvaluator;
+import org.apache.tiles.evaluator.AttributeEvaluatorFactory;
+import org.apache.tiles.evaluator.AttributeEvaluatorFactoryAware;
+import org.apache.tiles.preparer.ViewPreparer;
+import org.apache.tiles.preparer.factory.NoSuchPreparerException;
+import org.apache.tiles.preparer.factory.PreparerFactory;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.Request;
+import org.apache.tiles.request.render.CannotRenderException;
+import org.apache.tiles.request.render.Renderer;
+import org.apache.tiles.request.render.RendererFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Basic implementation of the tiles container interface.
+ * In most cases, this container will be customized by
+ * injecting customized services, not necessarily by
+ * override the container
+ *
+ * @since 2.0
+ * @version $Rev$ $Date$
+ */
+public class BasicTilesContainer implements TilesContainer,
+        AttributeEvaluatorFactoryAware {
+
+    /**
+     * Name used to store attribute context stack.
+     */
+    private static final String ATTRIBUTE_CONTEXT_STACK =
+        "org.apache.tiles.AttributeContext.STACK";
+
+    /**
+     * Log instance for all BasicTilesContainer
+     * instances.
+     */
+    private final Logger log = LoggerFactory
+            .getLogger(BasicTilesContainer.class);
+
+    /**
+     * The Tiles application context object.
+     */
+    private ApplicationContext context;
+
+    /**
+     * The definitions factory.
+     */
+    private DefinitionsFactory definitionsFactory;
+
+    /**
+     * The preparer factory.
+     */
+    private PreparerFactory preparerFactory;
+
+    /**
+     * The renderer factory.
+     */
+    private RendererFactory rendererFactory;
+
+    /**
+     * The attribute evaluator.
+     */
+    private AttributeEvaluatorFactory attributeEvaluatorFactory;
+
+    /** {@inheritDoc} */
+    public AttributeContext startContext(Request request) {
+        AttributeContext context = new BasicAttributeContext();
+        Deque<AttributeContext>  stack = getContextStack(request);
+        if (!stack.isEmpty()) {
+            AttributeContext parent = stack.peek();
+            context.inheritCascadedAttributes(parent);
+        }
+        stack.push(context);
+        return context;
+    }
+
+    /** {@inheritDoc} */
+    public void endContext(Request request) {
+        popContext(request);
+    }
+
+    /** {@inheritDoc} */
+    public void renderContext(Request request) {
+        AttributeContext attributeContext = getAttributeContext(request);
+
+        render(request, attributeContext);
+    }
+
+    /**
+     * Returns the Tiles application context used by this container.
+     *
+     * @return the application context for this container.
+     */
+    public ApplicationContext getApplicationContext() {
+        return context;
+    }
+
+    /**
+     * Sets the Tiles application context to use.
+     *
+     * @param context The Tiles application context.
+     */
+    public void setApplicationContext(ApplicationContext context) {
+        this.context = context;
+    }
+
+    /** {@inheritDoc} */
+    public AttributeContext getAttributeContext(Request request) {
+        AttributeContext context = getContext(request);
+        if (context == null) {
+            context = new BasicAttributeContext();
+            pushContext(context, request);
+        }
+        return context;
+
+    }
+
+    /**
+     * Returns the definitions factory.
+     *
+     * @return The definitions factory used by this container.
+     */
+    public DefinitionsFactory getDefinitionsFactory() {
+        return definitionsFactory;
+    }
+
+    /**
+     * Set the definitions factory. This method first ensures
+     * that the container has not yet been initialized.
+     *
+     * @param definitionsFactory the definitions factory for this instance.
+     */
+    public void setDefinitionsFactory(DefinitionsFactory definitionsFactory) {
+        this.definitionsFactory = definitionsFactory;
+    }
+
+    /**
+     * Returns the preparer factory used by this container.
+     *
+     * @return return the preparerInstance factory used by this container.
+     */
+    public PreparerFactory getPreparerFactory() {
+        return preparerFactory;
+    }
+
+    /**
+     * Set the preparerInstance factory.  This method first ensures
+     * that the container has not yet been initialized.
+     *
+     * @param preparerFactory the preparerInstance factory for this conainer.
+     */
+    public void setPreparerFactory(PreparerFactory preparerFactory) {
+        this.preparerFactory = preparerFactory;
+    }
+
+    /**
+     * Sets the renderer instance factory.
+     *
+     * @param rendererFactory the renderer instance factory for this container.
+     * @since 2.1.0
+     */
+    public void setRendererFactory(RendererFactory rendererFactory) {
+        this.rendererFactory = rendererFactory;
+    }
+
+    /** {@inheritDoc} */
+    public void setAttributeEvaluatorFactory(
+            AttributeEvaluatorFactory attributeEvaluatorFactory) {
+        this.attributeEvaluatorFactory = attributeEvaluatorFactory;
+    }
+
+    /** {@inheritDoc} */
+    public void prepare(String preparer, Request request) {
+        prepare(request, preparer, false);
+    }
+
+    /** {@inheritDoc} */
+    public void render(String definitionName, Request request) {
+        log.debug("Render request received for definition '{}'", definitionName);
+
+        Definition definition = getDefinition(definitionName, request);
+
+        if (definition == null) {
+            throw new NoSuchDefinitionException("Unable to find the definition '" + definitionName + "'");
+        }
+
+        render(definition, request);
+    }
+
+    /**
+     * Renders the specified definition.
+     * @param definition The definition to render.
+     * @param request The request context.
+     * @since 2.1.3
+     */
+    public void render(Definition definition, Request request) {
+        AttributeContext originalContext = getAttributeContext(request);
+        BasicAttributeContext subContext = new BasicAttributeContext(originalContext);
+        subContext.inherit(definition);
+
+        pushContext(subContext, request);
+
+        try {
+            render(request, subContext);
+        } finally {
+            popContext(request);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public void render(Attribute attr, Request request)
+        throws IOException {
+        if (attr == null) {
+            throw new CannotRenderException("Cannot render a null attribute");
+        }
+
+        if (attr.isPermitted(request)) {
+            Renderer renderer = rendererFactory.getRenderer(attr.getRenderer());
+            Object value = evaluate(attr, request);
+            if (!(value instanceof String)) {
+                throw new CannotRenderException(
+                        "Cannot render an attribute that is not a string, toString returns: "
+                                + value);
+            }
+            renderer.render((String) value, request);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public Object evaluate(Attribute attribute, Request request) {
+        AttributeEvaluator evaluator = attributeEvaluatorFactory
+                .getAttributeEvaluator(attribute);
+        return evaluator.evaluate(attribute, request);
+    }
+
+    /** {@inheritDoc} */
+    public boolean isValidDefinition(String definitionName, Request request) {
+        try {
+            Definition definition = getDefinition(definitionName, request);
+            return definition != null;
+        } catch (NoSuchDefinitionException nsde) {
+            log.debug("Cannot find definition '{}'", definitionName);
+            log.debug("Exception related to the not found definition", nsde);
+            return false;
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Definition getDefinition(String definitionName,
+            Request request) {
+        Definition definition =
+            definitionsFactory.getDefinition(definitionName, request);
+        return definition;
+    }
+
+    /**
+     * Returns the context stack.
+     *
+     * @param tilesContext The Tiles context object to use.
+     * @return The needed stack of contexts.
+     * @since 2.0.6
+     */
+    @SuppressWarnings("unchecked")
+    protected Deque<AttributeContext> getContextStack(Request tilesContext) {
+        Map<String, Object> requestScope = tilesContext.getContext("request");
+        Deque<AttributeContext> contextStack = (Deque<AttributeContext>) requestScope
+                .get(ATTRIBUTE_CONTEXT_STACK);
+        if (contextStack == null) {
+            contextStack = new LinkedList<AttributeContext>();
+            requestScope.put(ATTRIBUTE_CONTEXT_STACK, contextStack);
+        }
+
+        return contextStack;
+    }
+
+    /**
+     * Pushes a context object in the stack.
+     *
+     * @param context The context to push.
+     * @param tilesContext The Tiles context object to use.
+     * @since 2.0.6
+     */
+    protected void pushContext(AttributeContext context,
+            Request tilesContext) {
+        Deque<AttributeContext> contextStack = getContextStack(tilesContext);
+        contextStack.push(context);
+    }
+
+    /**
+     * Pops a context object out of the stack.
+     *
+     * @param tilesContext The Tiles context object to use.
+     * @return The popped context object.
+     * @since 2.0.6
+     */
+    protected AttributeContext popContext(Request tilesContext) {
+        Deque<AttributeContext> contextStack = getContextStack(tilesContext);
+        return contextStack.pop();
+    }
+
+    /**
+     * Get attribute context from request.
+     *
+     * @param tilesContext current Tiles application context.
+     * @return BasicAttributeContext or null if context is not found.
+     * @since 2.0.6
+     */
+    protected AttributeContext getContext(Request tilesContext) {
+        Deque<AttributeContext> contextStack = getContextStack(tilesContext);
+        if (!contextStack.isEmpty()) {
+            return contextStack.peek();
+        }
+        return null;
+    }
+
+    /**
+     * Execute a preparer.
+     *
+     * @param context The request context.
+     * @param preparerName The name of the preparer.
+     * @param ignoreMissing If <code>true</code> if the preparer is not found,
+     * it ignores the problem.
+     * @throws NoSuchPreparerException If the preparer is not found (and
+     * <code>ignoreMissing</code> is not set) or if the preparer itself threw an
+     * exception.
+     */
+    private void prepare(Request context, String preparerName, boolean ignoreMissing) {
+
+        log.debug("Prepare request received for '{}'", preparerName);
+
+        ViewPreparer preparer = preparerFactory.getPreparer(preparerName, context);
+        if (preparer == null && ignoreMissing) {
+            return;
+        }
+
+        if (preparer == null) {
+            throw new NoSuchPreparerException("Preparer '" + preparerName + " not found");
+        }
+
+        AttributeContext attributeContext = getContext(context);
+
+        preparer.execute(context, attributeContext);
+    }
+
+    /**
+     * Renders the specified attribute context.
+     *
+     * @param request The request context.
+     * @param attributeContext The context to render.
+     * @throws InvalidTemplateException If the template is not valid.
+     * @throws CannotRenderException If something goes wrong during rendering.
+     * @since 2.1.3
+     */
+    protected void render(Request request,
+            AttributeContext attributeContext) {
+
+        try {
+            if (attributeContext.getPreparer() != null) {
+                prepare(request, attributeContext.getPreparer(), true);
+            }
+
+            render(attributeContext.getTemplateAttribute(), request);
+        } catch (IOException e) {
+            throw new CannotRenderException(e.getMessage(), e);
+        }
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/impl/InvalidTemplateException.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/impl/InvalidTemplateException.java
new file mode 100644
index 000000000..660c2d416
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/impl/InvalidTemplateException.java
@@ -0,0 +1,71 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.impl;
+
+import org.apache.tiles.TilesException;
+
+/**
+ * An invalid template has been identified.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.1.0
+ */
+public class InvalidTemplateException extends TilesException {
+
+    /**
+     * Constructor.
+     *
+     * @since 2.1.0
+     */
+    public InvalidTemplateException() {
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param message The detail message.
+     * @since 2.1.0
+     */
+    public InvalidTemplateException(String message) {
+        super(message);
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param e The exception to be wrapped.
+     * @since 2.1.0
+     */
+    public InvalidTemplateException(Throwable e) {
+        super(e);
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param message The detail message.
+     * @param e The exception to be wrapped.
+     * @since 2.1.0
+     */
+    public InvalidTemplateException(String message, Throwable e) {
+        super(message, e);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/impl/mgmt/CachingTilesContainer.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/impl/mgmt/CachingTilesContainer.java
new file mode 100644
index 000000000..608ba4740
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/impl/mgmt/CachingTilesContainer.java
@@ -0,0 +1,242 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.impl.mgmt;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tiles.Definition;
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.TilesContainerWrapper;
+import org.apache.tiles.definition.NoSuchDefinitionException;
+import org.apache.tiles.mgmt.MutableTilesContainer;
+import org.apache.tiles.request.Request;
+
+/**
+ * Manages custom and configured definitions, so they can be used by the
+ * container, instead of using a simple {@link org.apache.tiles.definition.DefinitionsFactory}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class CachingTilesContainer extends TilesContainerWrapper implements MutableTilesContainer {
+
+    /**
+     * The default name of the attribute in which storing custom definitions.
+     */
+    private static final String DEFAULT_DEFINITIONS_ATTRIBUTE_NAME =
+        "org.apache.tiles.impl.mgmt.DefinitionManager.DEFINITIONS";
+
+    /**
+     * The name of the attribute in which storing custom definitions.
+     */
+    private String definitionsAttributeName;
+
+    /**
+     * Constructor.
+     * @param originalContainer The original container to wrap.
+     */
+    public CachingTilesContainer(TilesContainer originalContainer) {
+        super(originalContainer);
+        definitionsAttributeName = DEFAULT_DEFINITIONS_ATTRIBUTE_NAME;
+    }
+
+    /**
+     * Constructor.
+     * @param originalContainer The original container to wrap.
+     * @param definitionsAttributeName The name of the attribute in which
+     * storing custom definitions.
+     */
+    public CachingTilesContainer(TilesContainer originalContainer, String definitionsAttributeName) {
+        super(originalContainer);
+        this.definitionsAttributeName = definitionsAttributeName;
+        if (this.definitionsAttributeName == null) {
+            this.definitionsAttributeName = DEFAULT_DEFINITIONS_ATTRIBUTE_NAME;
+        }
+    }
+
+    /**
+     * Returns a definition by name.
+     *
+     * @param definition The name of the definition.
+     * @param request The current request.
+     * @return The requested definition, either main or custom.
+     * @throws org.apache.tiles.definition.DefinitionsFactoryException If
+     * something goes wrong when obtaining a main definition.
+     */
+    public Definition getDefinition(String definition,
+            Request request) {
+        Definition retValue = null;
+        retValue = getCustomDefinition(definition, request);
+        if (retValue == null) {
+            retValue = super.getDefinition(definition, request);
+        }
+        return retValue;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean isValidDefinition(String definition, Request request) {
+        if (getCustomDefinition(definition, request) != null) {
+            return true;
+        }
+        return super.isValidDefinition(definition, request);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void register(Definition definition, Request request) {
+        Map<String, Definition> definitions = getOrCreateDefinitions(request);
+        if (definition.getName() == null) {
+            definition.setName(getNextUniqueDefinitionName(definitions));
+        }
+
+        if (definition.isExtending()) {
+            this.resolveInheritance(definition, request);
+        }
+
+        definitions.put(definition.getName(), definition);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void render(String definition, Request request) {
+        Definition toRender = getDefinition(definition, request);
+        if (toRender == null) {
+            throw new NoSuchDefinitionException(
+                    "Cannot find definition named '" + definition + "'");
+        }
+        super.render(toRender, request);
+    }
+
+    /**
+     * Resolve inheritance.
+     * First, resolve parent's inheritance, then set template to the parent's
+     * template.
+     * Also copy attributes set in parent, and not set in child
+     * If instance doesn't extend anything, do nothing.
+     *
+     * @param definition The definition that needs to have its inheritances
+     * resolved.
+     * @param request The current request.
+     * @throws org.apache.tiles.definition.DefinitionsFactoryException If an
+     * inheritance can not be solved.
+     */
+    private void resolveInheritance(Definition definition,
+            Request request) {
+        // Already done, or not needed ?
+        if (!definition.isExtending()) {
+            return;
+        }
+
+        String parentDefinitionName = definition.getExtends();
+
+        boolean recurse = true;
+        Definition parent = getCustomDefinition(parentDefinitionName, request);
+        if (parent == null) {
+            parent = container.getDefinition(parentDefinitionName, request);
+            recurse = false;
+        }
+
+        if (parent == null) {
+            throw new NoSuchDefinitionException(
+                    "Error while resolving definition inheritance: child '"
+                            + definition.getName()
+                            + "' can't find its ancestor '"
+                            + parentDefinitionName
+                            + "'. Please check your description file.");
+        }
+
+        // Resolve parent before itself.
+        if (recurse) {
+            resolveInheritance(parent, request);
+        }
+        definition.inherit(parent);
+    }
+
+    /**
+     * Returns the map with custom definitions for the current request.
+     *
+     * @param request The current request.
+     * @return A map that connects a definition name to a definition.
+     */
+    @SuppressWarnings("unchecked")
+    private Map<String, Definition> getDefinitions(
+            Request request) {
+        return (Map<String, Definition>) request.getContext("request")
+                .get(definitionsAttributeName);
+    }
+
+    /**
+     * Returns a map of type "definition name -> definition" and, if it has not
+     * been defined before, creates one.
+     *
+     * @param request The current request.
+     * @return A map that connects a definition name to a definition.
+     */
+    @SuppressWarnings("unchecked")
+    private Map<String, Definition> getOrCreateDefinitions(
+            Request request) {
+        Map<String, Definition> definitions =
+            (Map<String, Definition>) request.getContext("request").get(definitionsAttributeName);
+        if (definitions == null) {
+            definitions = new HashMap<String, Definition>();
+            request.getContext("request")
+                    .put(definitionsAttributeName, definitions);
+        }
+
+        return definitions;
+    }
+
+    /**
+     * Create a unique definition name usable to store anonymous definitions.
+     *
+     * @param definitions The already created definitions.
+     * @return The unique definition name to be used to store the definition.
+     * @since 2.1.0
+     */
+    private String getNextUniqueDefinitionName(
+            Map<String, Definition> definitions) {
+        String candidate;
+        int anonymousDefinitionIndex = 1;
+
+        do {
+            candidate = "$anonymousMutableDefinition" + anonymousDefinitionIndex;
+            anonymousDefinitionIndex++;
+        } while (definitions.containsKey(candidate));
+
+        return candidate;
+    }
+
+    /**
+     * Returns a custom definition from the cache.
+     *
+     * @param definition The definition to search.
+     * @param request The request.
+     * @return The requested definition.
+     */
+    private Definition getCustomDefinition(String definition, Request request) {
+        Map<String, Definition> definitions = getDefinitions(request);
+        if (definitions != null) {
+            return definitions.get(definition);
+        }
+        return null;
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/impl/mgmt/package-info.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/impl/mgmt/package-info.java
new file mode 100644
index 000000000..beb028308
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/impl/mgmt/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * It contains the basic implementations of mutable Tiles containers.
+ */
+package org.apache.tiles.impl.mgmt;
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/impl/package-info.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/impl/package-info.java
new file mode 100644
index 000000000..4df849eab
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/impl/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * It contains the basic implementations of Tiles container.
+ */
+package org.apache.tiles.impl;
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/locale/LocaleResolver.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/locale/LocaleResolver.java
new file mode 100644
index 000000000..4022cc35b
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/locale/LocaleResolver.java
@@ -0,0 +1,42 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.locale;
+
+import java.util.Locale;
+
+import org.apache.tiles.request.Request;
+
+/**
+ * It represents an object able to resolve the current locale for the current
+ * request, where its strategy depends on its implementation.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface LocaleResolver {
+
+    /**
+     * Resolves the locale.
+     *
+     * @param request The Tiles request object.
+     * @return The current locale for the current request.
+     */
+    Locale resolveLocale(Request request);
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/locale/impl/DefaultLocaleResolver.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/locale/impl/DefaultLocaleResolver.java
new file mode 100644
index 000000000..19fd12f99
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/locale/impl/DefaultLocaleResolver.java
@@ -0,0 +1,57 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.locale.impl;
+
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.tiles.locale.LocaleResolver;
+import org.apache.tiles.request.Request;
+
+/**
+ * Default implementation of <code>LocaleResolver</code><br>
+ * It tries to take the locale from the session-scoped attribute
+ * {@link DefaultLocaleResolver#LOCALE_KEY}. If it is not found, it returns the
+ * locale included in the request.
+ *
+ * @version $Rev$ $Date$
+ */
+public class DefaultLocaleResolver implements LocaleResolver {
+
+    /**
+     * The attribute name that is used to store the current locale.
+     */
+    public static final String LOCALE_KEY = "org.apache.tiles.LOCALE";
+
+    /** {@inheritDoc} */
+    public Locale resolveLocale(Request request) {
+        Locale retValue = null;
+        Map<String, Object> session = request.getContext("session");
+        if (session != null) {
+            retValue = (Locale) session.get(DefaultLocaleResolver.LOCALE_KEY);
+        }
+        if (retValue == null) {
+            retValue = request.getRequestLocale();
+        }
+
+        return retValue;
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/locale/impl/package-info.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/locale/impl/package-info.java
new file mode 100644
index 000000000..8005c7bf0
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/locale/impl/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * Basic implementation of the locale resolver.
+ */
+package org.apache.tiles.locale.impl;
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/locale/package-info.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/locale/package-info.java
new file mode 100644
index 000000000..b9225e749
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/locale/package-info.java
@@ -0,0 +1,25 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * Classes and interfaces to allow locale resolution in an application, i.e. it
+ * allows to specify how to access the locale that the user wants to use.
+ */
+package org.apache.tiles.locale;
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/preparer/factory/BasicPreparerFactory.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/preparer/factory/BasicPreparerFactory.java
new file mode 100644
index 000000000..e116c87a7
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/preparer/factory/BasicPreparerFactory.java
@@ -0,0 +1,101 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.preparer.factory;
+
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.tiles.preparer.ViewPreparer;
+import org.apache.tiles.request.Request;
+import org.apache.tiles.request.reflect.ClassUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Default implementation of the {@link PreparerFactory}.
+ * This factory provides no contextual configuration.  It
+ * simply instantiates the named preparerInstance and returns it.
+ *
+ * @since Tiles 2.0
+ * @version $Rev$ $Date$
+ */
+public class BasicPreparerFactory implements PreparerFactory {
+
+    /**
+     * The logging object.
+     */
+    private final Logger log = LoggerFactory
+            .getLogger(BasicPreparerFactory.class);
+
+    /**
+     * Maps a preparer name to the instantiated preparer.
+     */
+    protected Map<String, ViewPreparer> preparers;
+    protected Set<String> knownPreparers;
+
+    /**
+     * Constructor.
+     */
+    public BasicPreparerFactory() {
+        this.preparers = new ConcurrentHashMap<String, ViewPreparer>();
+        this.knownPreparers = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>());
+    }
+
+
+    /**
+     * Create a new instance of the named preparerInstance.  This factory
+     * expects all names to be qualified class names.
+     *
+     * @param name    the named preparerInstance
+     * @param context current context
+     * @return ViewPreparer instance
+     */
+    public ViewPreparer getPreparer(String name, Request context) {
+
+        if (!knownPreparers.contains(name)) {
+            knownPreparers.add(name);
+            ViewPreparer preparer = createPreparer(name);
+            if (preparer != null) {
+               preparers.put(name, preparer);
+            }
+        }
+
+        return preparers.get(name);
+    }
+
+    /**
+     * Creates a view preparer for the given name.
+     *
+     * @param name The name of the preparer.
+     * @return The created preparer.
+     */
+    protected ViewPreparer createPreparer(String name) {
+
+        log.debug("Creating ViewPreparer '{}' . . .", name);
+
+        Object instance = ClassUtil.instantiate(name, true);
+        log.debug("ViewPreparer created successfully");
+        return (ViewPreparer) instance;
+
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/preparer/factory/NoSuchPreparerException.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/preparer/factory/NoSuchPreparerException.java
new file mode 100644
index 000000000..ed57cd3e7
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/preparer/factory/NoSuchPreparerException.java
@@ -0,0 +1,67 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.preparer.factory;
+
+import org.apache.tiles.preparer.PreparerException;
+
+/**
+ * Thrown when the named preparerInstance can not be found.
+ *
+ * @since 2.0
+ * @version $Rev$ $Date$
+ */
+public class NoSuchPreparerException extends PreparerException {
+
+    /**
+     * Constructor.
+     */
+    public NoSuchPreparerException() {
+        super();
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param message The message to include.
+     */
+    public NoSuchPreparerException(String message) {
+        super(message);
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param e The cause exception.
+     */
+    public NoSuchPreparerException(Throwable e) {
+        super(e);
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param message The message to include.
+     * @param e The cause exception.
+     */
+    public NoSuchPreparerException(String message, Throwable e) {
+        super(message, e);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/preparer/factory/PreparerFactory.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/preparer/factory/PreparerFactory.java
new file mode 100644
index 000000000..2575d7e71
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/preparer/factory/PreparerFactory.java
@@ -0,0 +1,53 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.preparer.factory;
+
+import org.apache.tiles.preparer.ViewPreparer;
+import org.apache.tiles.request.Request;
+
+/**
+ * <p>
+ * Factory interface used to create/retrieve instances of
+ * the {@link ViewPreparer} interface.
+ * <p/>
+ *
+ * <p>
+ * This factory provides an extension point into the default
+ * tiles implementation. Implementors wishing to provide
+ * per request initialization of the ViewPreparer (for instance)
+ * may provide a custom prerparer.
+ * </p>
+ *
+ * @since 2.0
+ *
+ * @version $Rev$ $Date$
+ */
+public interface PreparerFactory {
+
+    /**
+     * Create the named {link ViewPreparer} for the specified context.
+     *
+     * @param name    ViewPreparer name, commonly the qualified classname.
+     * @param context the context within which the preparerInstance will be invoked.
+     * @return instance of the ViewPreparer
+     */
+    ViewPreparer getPreparer(String name, Request context);
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/preparer/factory/package-info.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/preparer/factory/package-info.java
new file mode 100644
index 000000000..ea80abef1
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/preparer/factory/package-info.java
@@ -0,0 +1,28 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * "View preparers" are objects that allows the "preparation" of a Tiles artifact
+ * (definition, template or attribute) before it is rendered.<br>
+ * It is useful, for example, when a view item should be built and stored in a
+ * particular context (e.g. a menu) and then rendered.
+ */
+package org.apache.tiles.preparer.factory;
+
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/renderer/DefinitionRenderer.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/renderer/DefinitionRenderer.java
new file mode 100644
index 000000000..84a794313
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/renderer/DefinitionRenderer.java
@@ -0,0 +1,66 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.renderer;
+
+import java.io.IOException;
+
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.request.Request;
+import org.apache.tiles.request.render.CannotRenderException;
+import org.apache.tiles.request.render.Renderer;
+
+/**
+ * Renders an attribute that contains a reference to a definition.
+ *
+ * @version $Rev$ $Date$
+ * @since 3.0.0
+ */
+public class DefinitionRenderer implements Renderer {
+
+    /**
+     * The Tiles container.
+     */
+    private TilesContainer container;
+
+    /**
+     * Constructor.
+     *
+     * @param container The Tiles container.
+     */
+    public DefinitionRenderer(TilesContainer container) {
+        this.container = container;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void render(String path, Request request) throws IOException {
+        if (path == null) {
+            throw new CannotRenderException("Cannot dispatch a null path");
+        }
+
+        container.render(path, request);
+    }
+
+    /** {@inheritDoc} */
+    public boolean isRenderable(String path, Request request) {
+        return path != null && container.isValidDefinition(path, request);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/renderer/package-info.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/renderer/package-info.java
new file mode 100644
index 000000000..8e58cfd8b
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/renderer/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * Interfaces to manage attribute rendering.
+ */
+package org.apache.tiles.renderer;
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/startup/AbstractTilesInitializer.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/startup/AbstractTilesInitializer.java
new file mode 100644
index 000000000..5d8fc7a20
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/startup/AbstractTilesInitializer.java
@@ -0,0 +1,127 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.startup;
+
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.access.TilesAccess;
+import org.apache.tiles.factory.AbstractTilesContainerFactory;
+import org.apache.tiles.request.ApplicationAccess;
+import org.apache.tiles.request.ApplicationContext;
+
+/**
+ * Default Tiles initialization delegate implementation under a servlet
+ * environment. It uses init parameters to create the
+ * {@link ApplicationContext} and the {@link TilesContainer}.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public abstract class AbstractTilesInitializer implements TilesInitializer {
+
+    /**
+     * Init parameter to define the key under which the container will be
+     * stored.
+     *
+     * @since 2.1.2
+     */
+    public static final String CONTAINER_KEY_INIT_PARAMETER =
+        "org.apache.tiles.startup.AbstractTilesInitializer.CONTAINER_KEY";
+
+    /**
+     * The initialized application context.
+     */
+    private ApplicationContext applicationContext;
+
+    /**
+     * The initialized container.
+     */
+    private TilesContainer container;
+
+    /** {@inheritDoc} */
+    public void initialize(ApplicationContext applicationContext) {
+        this.applicationContext = createTilesApplicationContext(applicationContext);
+        ApplicationAccess.register(applicationContext);
+        String key = getContainerKey(this.applicationContext);
+        container = createContainer(this.applicationContext);
+        TilesAccess.setContainer(this.applicationContext, container, key);
+    }
+
+    /** {@inheritDoc} */
+    public void destroy() {
+        TilesAccess.setContainer(applicationContext, null,
+                getContainerKey(applicationContext));
+    }
+
+    /**
+     * Creates the Tiles application context, to be used across all the
+     * Tiles-based application. If you override this class, please override this
+     * method or
+     * {@link #createAndInitializeTilesApplicationContextFactory(ApplicationContext)}
+     * .<br>
+     * This implementation returns the preliminary context passed as a parameter
+     *
+     * @param preliminaryContext The preliminary application context to use.
+     * @return The Tiles application context.
+     * @since 2.2.0
+     */
+    protected ApplicationContext createTilesApplicationContext(
+            ApplicationContext preliminaryContext) {
+        return preliminaryContext;
+    }
+
+    /**
+     * Returns the container key under which the container will be stored.
+     * This implementation returns <code>null</code> so that the container will
+     * be the default one.
+     *
+     * @param applicationContext The Tiles application context to use.
+     * @return The container key.
+     * @since 2.2.0
+     */
+    protected String getContainerKey(ApplicationContext applicationContext) {
+        return null;
+    }
+
+    /**
+     * Creates a Tiles container. If you override this class, please override
+     * this method or {@link #createContainerFactory(ApplicationContext)}.
+     *
+     * @param context The servlet context to use.
+     * @return The created container.
+     * @since 2.2.0
+     */
+    protected TilesContainer createContainer(ApplicationContext context) {
+        AbstractTilesContainerFactory factory = createContainerFactory(context);
+        return factory.createContainer(context);
+    }
+
+    /**
+     * Creates a Tiles container factory. If you override this class, please
+     * override this method or {@link #createContainer(ApplicationContext)}.
+     *
+     * @param context The servlet context to use.
+     * @return The created container factory.
+     * @since 2.2.0
+     */
+    protected abstract AbstractTilesContainerFactory createContainerFactory(
+            ApplicationContext context);
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/startup/DefaultTilesInitializer.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/startup/DefaultTilesInitializer.java
new file mode 100644
index 000000000..c0f3796bb
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/startup/DefaultTilesInitializer.java
@@ -0,0 +1,42 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.startup;
+
+import org.apache.tiles.factory.AbstractTilesContainerFactory;
+import org.apache.tiles.factory.BasicTilesContainerFactory;
+import org.apache.tiles.request.ApplicationContext;
+
+/**
+ * Loads Tiles with the default settings.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public class DefaultTilesInitializer extends AbstractTilesInitializer {
+
+    /** {@inheritDoc} */
+    @Override
+    protected AbstractTilesContainerFactory createContainerFactory(
+            ApplicationContext context) {
+        return new BasicTilesContainerFactory();
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/startup/TilesInitializer.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/startup/TilesInitializer.java
new file mode 100644
index 000000000..539f9a9f7
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/startup/TilesInitializer.java
@@ -0,0 +1,49 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.startup;
+
+import org.apache.tiles.request.ApplicationContext;
+
+/**
+ * Tiles initialization delegate. It initializes Tiles container(s) and the
+ * application context to use across all the application.
+ *
+ * @version $Rev$ $Date$
+ */
+public interface TilesInitializer {
+
+    /**
+     * Initializes Tiles.
+     *
+     * @param preliminaryContext The preliminary application context to use. It
+     * will be overwritten with the real instance later. Use a context usable
+     * under your current environment, like ServletTilesApplicationContext or
+     * PortletTilesApplicationContext.
+     */
+    void initialize(ApplicationContext preliminaryContext);
+
+    /**
+     * Destroys the Tiles container.
+     *
+     * @since 2.2.0
+     */
+    void destroy();
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/startup/package-info.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/startup/package-info.java
new file mode 100644
index 000000000..f102e1b59
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/startup/package-info.java
@@ -0,0 +1,26 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * Classes to start the Tiles engine up. Use these classes in your environment by
+ * using a preliminary TilesApplicationContext that expose at least the needed
+ * initialization parameters.
+ */
+package org.apache.tiles.startup;
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/util/CombinedBeanInfo.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/util/CombinedBeanInfo.java
new file mode 100644
index 000000000..4a962e409
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/util/CombinedBeanInfo.java
@@ -0,0 +1,100 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.util;
+
+import java.beans.FeatureDescriptor;
+import java.beans.PropertyDescriptor;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.tiles.request.reflect.ClassUtil;
+
+/**
+ * Contains the bean infos about one or more classes.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public class CombinedBeanInfo {
+    /**
+     * The descriptors of the introspected classes.
+     */
+    private List<FeatureDescriptor> descriptors;
+
+    /**
+     * Maps analyzed classes to the map of introspected properties.
+     */
+    private Map<Class<?>, Map<String, PropertyDescriptor>> class2descriptors;
+
+    /**
+     * Constructor.
+     * @param clazzes The list of classes to analyze and combine.
+     *
+     * @since 2.2.0
+     */
+    public CombinedBeanInfo(Class<?>... clazzes) {
+        descriptors = new ArrayList<FeatureDescriptor>();
+        class2descriptors = new LinkedHashMap<Class<?>, Map<String, PropertyDescriptor>>();
+        for (int i = 0; i < clazzes.length; i++) {
+            Class<?> clazz = clazzes[i];
+            Map<String, PropertyDescriptor> mappedDescriptors = new LinkedHashMap<String, PropertyDescriptor>();
+            ClassUtil.collectBeanInfo(clazz, mappedDescriptors);
+            descriptors.addAll(mappedDescriptors.values());
+            class2descriptors.put(clazz, mappedDescriptors);
+        }
+    }
+
+    /**
+     * Returns the descriptors of all the introspected classes.
+     *
+     * @return The feature descriptors.
+     * @since 2.2.0
+     */
+    public List<FeatureDescriptor> getDescriptors() {
+        return descriptors;
+    }
+
+    /**
+     * Returns a map of the introspected properties for the given class.
+     *
+     * @param clazz The class to get the properties from.
+     * @return The map of property descriptors.
+     * @since 2.2.0
+     */
+    public Map<String, PropertyDescriptor> getMappedDescriptors(Class<?> clazz) {
+        return class2descriptors.get(clazz);
+    }
+
+    /**
+     * Returns the set of properties for the given introspected class.
+     *
+     * @param clazz The class to get the properties from.
+     * @return The set of properties.
+     * @since 2.2.0
+     */
+    public Set<String> getProperties(Class<?> clazz) {
+        return class2descriptors.get(clazz).keySet();
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/util/WildcardHelper.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/util/WildcardHelper.java
new file mode 100644
index 000000000..74632439b
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/util/WildcardHelper.java
@@ -0,0 +1,548 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.util;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * This class is an utility class that perform wilcard-patterns matching and
+ * isolation taken from Apache Struts that is taken, in turn, from Apache
+ * Struts.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.1.0
+ */
+public class WildcardHelper {
+    /**
+     * The int representing '*' in the pattern <code>int []</code>.
+     *
+     * @since 2.1.0
+     */
+    protected static final int MATCH_FILE = -1;
+
+    /**
+     * The int representing '**' in the pattern <code>int []</code>.
+     *
+     * @since 2.1.0
+     */
+    protected static final int MATCH_PATH = -2;
+
+    /**
+     * The int representing begin in the pattern <code>int []</code>.
+     *
+     * @since 2.1.0
+     */
+    protected static final int MATCH_BEGIN = -4;
+
+    /**
+     * The int representing end in pattern <code>int []</code>.
+     *
+     * @since 2.1.0
+     */
+    protected static final int MATCH_THEEND = -5;
+
+    /**
+     * The int value that terminates the pattern <code>int []</code>.
+     *
+     * @since 2.1.0
+     */
+    protected static final int MATCH_END = -3;
+
+    /**
+     * The length of the placeholder.
+     *
+     * @since 2.1.0
+     */
+    private static final int PLACEHOLDER_LENGTH = 3;
+
+    /**
+     * <p>
+     * Translate the given <code>String</code> into a <code>int []</code>
+     * representing the pattern matchable by this class. <br>
+     * This function translates a <code>String</code> into an int array
+     * converting the special '*' and '\' characters. <br>
+     * Here is how the conversion algorithm works:
+     * </p>
+     *
+     * <ul>
+     *
+     * <li>The '*' character is converted to MATCH_FILE, meaning that zero or
+     * more characters (excluding the path separator '/') are to be matched.</li>
+     *
+     * <li>The '**' sequence is converted to MATCH_PATH, meaning that zero or
+     * more characters (including the path separator '/') are to be matched.</li>
+     *
+     * <li>The '\' character is used as an escape sequence ('\*' is translated
+     * in '*', not in MATCH_FILE). If an exact '\' character is to be matched
+     * the source string must contain a '\\'. sequence.</li>
+     *
+     * </ul>
+     *
+     * <p>
+     * When more than two '*' characters, not separated by another character,
+     * are found their value is considered as '**' (MATCH_PATH). <br>
+     * The array is always terminated by a special value (MATCH_END). <br>
+     * All MATCH* values are less than zero, while normal characters are equal
+     * or greater.
+     * </p>
+     *
+     * @param data The string to translate.
+     * @return The encoded string as an int array, terminated by the MATCH_END
+     * value (don't consider the array length).
+     * @throws NullPointerException If data is null.
+     * @since 2.1.0
+     */
+    public int[] compilePattern(String data) {
+        // Prepare the arrays
+        int[] expr = new int[data.length() + 2];
+        char[] buff = data.toCharArray();
+
+        // Prepare variables for the translation loop
+        int y = 0;
+        boolean slash = false;
+
+        // Must start from beginning
+        expr[y++] = MATCH_BEGIN;
+
+        if (buff.length > 0) {
+            if (buff[0] == '\\') {
+                slash = true;
+            } else if (buff[0] == '*') {
+                expr[y++] = MATCH_FILE;
+            } else {
+                expr[y++] = buff[0];
+            }
+
+            // Main translation loop
+            for (int x = 1; x < buff.length; x++) {
+                // If the previous char was '\' simply copy this char.
+                if (slash) {
+                    expr[y++] = buff[x];
+                    slash = false;
+
+                    // If the previous char was not '\' we have to do a bunch of
+                    // checks
+                } else {
+                    // If this char is '\' declare that and continue
+                    if (buff[x] == '\\') {
+                        slash = true;
+
+                        // If this char is '*' check the previous one
+                    } else if (buff[x] == '*') {
+                        // If the previous character als was '*' match a path
+                        if (expr[y - 1] <= MATCH_FILE) {
+                            expr[y - 1] = MATCH_PATH;
+                        } else {
+                            expr[y++] = MATCH_FILE;
+                        }
+                    } else {
+                        expr[y++] = buff[x];
+                    }
+                }
+            }
+        }
+
+        // Must match end at the end
+        expr[y] = MATCH_THEEND;
+
+        return expr;
+    }
+
+    /**
+     * Match a pattern agains a string and isolates wildcard replacement into a
+     * <code>Stack</code>.
+     *
+     * @param data The string to match
+     * @param expr The compiled wildcard expression
+     * @return The list of matched variables, or <code>null</code> if it does not match.
+     * @throws NullPointerException If any parameters are null
+     * @since 2.2.0
+     */
+    public List<String> match(String data, int[] expr) {
+        List<String> varsValues = null;
+
+        if (data == null) {
+            throw new NullPointerException("No data provided");
+        }
+
+        if (expr == null) {
+            throw new NullPointerException("No pattern expression provided");
+        }
+
+        char[] buff = data.toCharArray();
+
+        // Allocate the result buffer
+        char[] rslt = new char[expr.length + buff.length];
+
+        // The previous and current position of the expression character
+        // (MATCH_*)
+        int charpos = 0;
+
+        // The position in the expression, input, translation and result arrays
+        int exprpos = 0;
+        int buffpos = 0;
+        int rsltpos = 0;
+        int offset = -1;
+
+        // First check for MATCH_BEGIN
+        boolean matchBegin = false;
+
+        if (expr[charpos] == MATCH_BEGIN) {
+            matchBegin = true;
+            exprpos = ++charpos;
+        }
+
+        // Search the fist expression character (except MATCH_BEGIN - already
+        // skipped)
+        while (expr[charpos] >= 0) {
+            charpos++;
+        }
+
+        // The expression charater (MATCH_*)
+        int exprchr = expr[charpos];
+
+        while (true) {
+            // Check if the data in the expression array before the current
+            // expression character matches the data in the input buffer
+            if (matchBegin) {
+                if (!matchArray(expr, exprpos, charpos, buff, buffpos)) {
+                    return null;
+                }
+
+                matchBegin = false;
+            } else {
+                offset = indexOfArray(expr, exprpos, charpos, buff, buffpos);
+
+                if (offset < 0) {
+                    return null;
+                }
+            }
+
+            // Check for MATCH_BEGIN
+            if (matchBegin) {
+                if (offset != 0) {
+                    return null;
+                }
+
+                matchBegin = false;
+            }
+
+            // Advance buffpos
+            buffpos += (charpos - exprpos);
+
+            // Check for END's
+            if (exprchr == MATCH_END) {
+                if (rsltpos > 0) {
+                    varsValues = addAndCreateList(varsValues, new String(rslt,
+                            0, rsltpos));
+                }
+
+                // Don't care about rest of input buffer
+                varsValues = addElementOnTop(varsValues, data);
+                return varsValues;
+            } else if (exprchr == MATCH_THEEND) {
+                if (rsltpos > 0) {
+                    varsValues = addAndCreateList(varsValues, new String(rslt,
+                            0, rsltpos));
+                }
+
+                // Check that we reach buffer's end
+                if (buffpos == buff.length) {
+                    addElementOnTop(varsValues, data);
+                    return varsValues;
+                }
+                return null;
+            }
+
+            // Search the next expression character
+            exprpos = ++charpos;
+
+            while (expr[charpos] >= 0) {
+                charpos++;
+            }
+
+            int prevchr = exprchr;
+
+            exprchr = expr[charpos];
+
+            // We have here prevchr == * or **.
+            offset = (prevchr == MATCH_FILE) ? indexOfArray(expr, exprpos,
+                    charpos, buff, buffpos) : lastIndexOfArray(expr, exprpos,
+                    charpos, buff, buffpos);
+
+            if (offset < 0) {
+                return null;
+            }
+
+            // Copy the data from the source buffer into the result buffer
+            // to substitute the expression character
+            if (prevchr == MATCH_PATH) {
+                while (buffpos < offset) {
+                    rslt[rsltpos++] = buff[buffpos++];
+                }
+            } else {
+                // Matching file, don't copy '/'
+                while (buffpos < offset) {
+                    if (buff[buffpos] == '/') {
+                        return null;
+                    }
+
+                    rslt[rsltpos++] = buff[buffpos++];
+                }
+            }
+
+            varsValues = addAndCreateList(varsValues, new String(rslt, 0,
+                    rsltpos));
+            rsltpos = 0;
+        }
+    }
+
+    /**
+     * Get the offset of a part of an int array within a char array. <br>
+     * This method return the index in d of the first occurrence after dpos of
+     * that part of array specified by r, starting at rpos and terminating at
+     * rend.
+     *
+     * @param r The array containing the data that need to be matched in d.
+     * @param rpos The index of the first character in r to look for.
+     * @param rend The index of the last character in r to look for plus 1.
+     * @param d The array of char that should contain a part of r.
+     * @param dpos The starting offset in d for the matching.
+     * @return The offset in d of the part of r matched in d or -1 if that was
+     * not found.
+     * @since 2.1.0
+     */
+    protected int indexOfArray(int[] r, int rpos, int rend, char[] d, int dpos) {
+        // Check if pos and len are legal
+        if (rend < rpos) {
+            throw new IllegalArgumentException("rend < rpos");
+        }
+
+        // If we need to match a zero length string return current dpos
+        if (rend == rpos) {
+            return (d.length); // ?? dpos?
+        }
+
+        // If we need to match a 1 char length string do it simply
+        if ((rend - rpos) == 1) {
+            // Search for the specified character
+            for (int x = dpos; x < d.length; x++) {
+                if (r[rpos] == d[x]) {
+                    return (x);
+                }
+            }
+        }
+
+        // Main string matching loop. It gets executed if the characters to
+        // match are less then the characters left in the d buffer
+        while (((dpos + rend) - rpos) <= d.length) {
+            // Set current startpoint in d
+            int y = dpos;
+
+            // Check every character in d for equity. If the string is matched
+            // return dpos
+            for (int x = rpos; x <= rend; x++) {
+                if (x == rend) {
+                    return (dpos);
+                }
+
+                if (r[x] != d[y++]) {
+                    break;
+                }
+            }
+
+            // Increase dpos to search for the same string at next offset
+            dpos++;
+        }
+
+        // The remaining chars in d buffer were not enough or the string
+        // wasn't matched
+        return (-1);
+    }
+
+    /**
+     * Get the offset of a last occurance of an int array within a char array.
+     * <br>
+     * This method return the index in d of the last occurrence after dpos of
+     * that part of array specified by r, starting at rpos and terminating at
+     * rend.
+     *
+     * @param r The array containing the data that need to be matched in d.
+     * @param rpos The index of the first character in r to look for.
+     * @param rend The index of the last character in r to look for plus 1.
+     * @param d The array of char that should contain a part of r.
+     * @param dpos The starting offset in d for the matching.
+     * @return The offset in d of the last part of r matched in d or -1 if that
+     * was not found.
+     * @since 2.1.0
+     */
+    protected int lastIndexOfArray(int[] r, int rpos, int rend, char[] d,
+            int dpos) {
+        // Check if pos and len are legal
+        if (rend < rpos) {
+            throw new IllegalArgumentException("rend < rpos");
+        }
+
+        // If we need to match a zero length string return current dpos
+        if (rend == rpos) {
+            return (d.length); // ?? dpos?
+        }
+
+        // If we need to match a 1 char length string do it simply
+        if ((rend - rpos) == 1) {
+            // Search for the specified character
+            for (int x = d.length - 1; x > dpos; x--) {
+                if (r[rpos] == d[x]) {
+                    return (x);
+                }
+            }
+        }
+
+        // Main string matching loop. It gets executed if the characters to
+        // match are less then the characters left in the d buffer
+        int l = d.length - (rend - rpos);
+
+        while (l >= dpos) {
+            // Set current startpoint in d
+            int y = l;
+
+            // Check every character in d for equity. If the string is matched
+            // return dpos
+            for (int x = rpos; x <= rend; x++) {
+                if (x == rend) {
+                    return (l);
+                }
+
+                if (r[x] != d[y++]) {
+                    break;
+                }
+            }
+
+            // Decrease l to search for the same string at next offset
+            l--;
+        }
+
+        // The remaining chars in d buffer were not enough or the string
+        // wasn't matched
+        return (-1);
+    }
+
+    /**
+     * Matches elements of array r from rpos to rend with array d, starting from
+     * dpos. <br>
+     * This method return true if elements of array r from rpos to rend equals
+     * elements of array d starting from dpos to dpos+(rend-rpos).
+     *
+     * @param r The array containing the data that need to be matched in d.
+     * @param rpos The index of the first character in r to look for.
+     * @param rend The index of the last character in r to look for.
+     * @param d The array of char that should start from a part of r.
+     * @param dpos The starting offset in d for the matching.
+     * @return true if array d starts from portion of array r.
+     * @since 2.1.0
+     */
+    protected boolean matchArray(int[] r, int rpos, int rend, char[] d, int dpos) {
+        if ((d.length - dpos) < (rend - rpos)) {
+            return (false);
+        }
+
+        for (int i = rpos; i < rend; i++) {
+            if (r[i] != d[dpos++]) {
+                return (false);
+            }
+        }
+
+        return (true);
+    }
+
+    /**
+     * <p>
+     * Inserts into a value wildcard-matched strings where specified.
+     * </p>
+     *
+     * @param val The value to convert
+     * @param vars A Map of wildcard-matched strings
+     * @return The new value
+     * @since 2.1.0
+     */
+    public static String convertParam(String val, Map<Integer, String> vars) {
+        if (val == null) {
+            return null;
+        } else if (val.indexOf("{") == -1) {
+            return val;
+        }
+
+        Map.Entry<Integer, String> entry;
+        StringBuilder key = new StringBuilder("{0}");
+        StringBuilder ret = new StringBuilder(val);
+        String keyTmp;
+        int x;
+
+        for (Iterator<Map.Entry<Integer, String>> i = vars.entrySet()
+                .iterator(); i.hasNext();) {
+            entry = i.next();
+            key.setCharAt(1, entry.getKey().toString().charAt(0));
+            keyTmp = key.toString();
+
+            // Replace all instances of the placeholder
+            while ((x = ret.toString().indexOf(keyTmp)) > -1) {
+                ret.replace(x, x + PLACEHOLDER_LENGTH, entry.getValue());
+            }
+        }
+
+        return ret.toString();
+    }
+
+    /**
+     * Adds and object to a list. If the list is null, it creates it.
+     *
+     * @param <T> The type of the element.
+     * @param list The list.
+     * @param data The data to add.
+     * @return The list itself, or a new one if it is <code>null</code>.
+     */
+    private <T> List<T> addAndCreateList(List<T> list, T data) {
+        if (list == null) {
+            list = new ArrayList<T>();
+        }
+        list.add(data);
+        return list;
+    }
+
+    /**
+     * Adds and object on top of a list. If the list is null, it creates it.
+     *
+     * @param <T> The type of the element.
+     * @param list The list.
+     * @param data The data to add.
+     * @return The list itself, or a new one if it is <code>null</code>.
+     */
+    private <T> List<T> addElementOnTop(List<T> list, T data) {
+        if (list == null) {
+            list = new ArrayList<T>();
+        }
+        list.add(0, data);
+        return list;
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/util/package-info.java b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/util/package-info.java
new file mode 100644
index 000000000..2854d4433
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/java/org/apache/tiles/util/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * Static utility classes used throughout the implementation.
+ */
+package org.apache.tiles.util;
diff --git a/Java-base/tiles/src/tiles-core/src/main/resources/LICENSE.txt b/Java-base/tiles/src/tiles-core/src/main/resources/LICENSE.txt
new file mode 100644
index 000000000..d64569567
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/resources/LICENSE.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/Java-base/tiles/src/tiles-core/src/main/resources/NOTICE.txt b/Java-base/tiles/src/tiles-core/src/main/resources/NOTICE.txt
new file mode 100644
index 000000000..1f13ff856
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/resources/NOTICE.txt
@@ -0,0 +1,6 @@
+   Apache Tiles
+   Copyright 1999-2009 The Apache Software Foundation
+
+   This product includes software developed at
+   The Apache Software Foundation (http://www.apache.org/).
+
diff --git a/Java-base/tiles/src/tiles-core/src/main/resources/org/apache/tiles/resources/tiles-config_3_0.dtd b/Java-base/tiles/src/tiles-core/src/main/resources/org/apache/tiles/resources/tiles-config_3_0.dtd
new file mode 100644
index 000000000..b8d3dd857
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/main/resources/org/apache/tiles/resources/tiles-config_3_0.dtd
@@ -0,0 +1,246 @@
+<!--
+%
+   $Id$
+
+   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.
+
+%
+
+@hidden $Id$
+@title DTD for the Tiles Definition File, Version 3.0
+@doctype tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN" "http://tiles.apache.org/dtds/tiles-config_3_0.dtd"
+@root tiles-definitions
+-->
+
+
+<!-- ========== Defined Types ============================================= -->
+
+
+<!-- A "Boolean" is the string representation of a boolean (true or false)
+     variable.
+-->
+<!ENTITY % Boolean "(true|false)">
+
+
+<!-- A "ContentType" is the content type of an attribute passed to a template.
+-->
+<!ENTITY % ContentType "CDATA">
+
+<!-- A "ClassName" is the fully qualified name of a Java class that is
+     instantiated to provide the functionality of the enclosing element.
+-->
+<!ENTITY % ClassName "CDATA">
+
+<!-- A "RequestPath" is an module-relative URI path, beginning with a
+     slash, that identifies a mapped resource (such as a JSP page or a servlet)
+     within this web application.
+-->
+<!ENTITY % RequestPath "CDATA">
+
+<!-- A "DefinitionName" is the unique identifier of a definition. This identifier
+     is a logical name used to reference the definition.
+-->
+<!ENTITY % DefinitionName "CDATA">
+
+<!-- A "Location" is a relative path, delimited by "/" characters, that
+     defines the location of a resource relative to the location of the
+     configuration file itself.
+-->
+<!ENTITY % Location "#PCDATA">
+
+
+
+<!-- ========== Top Level Elements ======================================== -->
+
+
+<!-- The "tiles-definitions" element is the root of the configuration file
+     hierarchy, and contains nested elements for all of the other
+     configuration settings.
+-->
+<!ELEMENT tiles-definitions (definition+)>
+
+<!-- The "definition" element describes a definition that can be inserted in a jsp
+     page. This definition is identified by its logical name. A definition allows
+     to define all the attributes that can be set in <insert> tag from a jsp page.
+-->
+<!ELEMENT definition (put-attribute*, put-list-attribute*)>
+<!ATTLIST definition       id               ID               #IMPLIED>
+<!--
+@attr preparer       The fully qualified Java class name of the preparer
+                     subclass to call immediately before the tiles is inserted.
+                     Only one of preparerClass or preparerUrl should be
+                     specified.
+-->
+<!ATTLIST definition       preparer         %ClassName;      #IMPLIED>
+<!--
+@attr extends        Name of a definition that is used as ancestor of this definition.
+                     All attributes from the ancestor are available to the new
+                     definition. Any attribute inherited from the ancestor can
+                     be overloaded by providing a new value.
+-->
+<!ATTLIST definition       extends          %DefinitionName; #IMPLIED>
+<!--
+@attr name           The unique identifier for this definition. Required when
+                     it is a root definition, while it is implied in nested
+                     definitions.
+-->
+<!ATTLIST definition       name             %DefinitionName; #IMPLIED>
+<!--
+@attr role           Security role name that is allowed access to this definition
+                     object. The definition is inserted only if the role name is
+                     allowed.
+-->
+<!ATTLIST definition       role             CDATA            #IMPLIED>
+<!--
+@attr template       The context-relative path to the resource used as tiles to
+                     insert. This tiles will be inserted and a tiles context
+                     containing appropriate attributes will be available.
+-->
+<!ATTLIST definition       template         %RequestPath;    #IMPLIED>
+<!--
+@attr templateExpression The expression that will evaluate to a template for this definition.
+               This attribute will be ignored if template is specified.
+
+-->
+<!ATTLIST definition       templateExpression       CDATA    #IMPLIED>
+<!--
+@attr templateType   The type of the template attribute. Can be: string,
+           template or definition.
+                     By default, the type is "template". If a type is
+                     associated, the desidered renderer will be invoked.
+-->
+<!ATTLIST definition       templateType             %ContentType;   #IMPLIED>
+
+<!-- The "put-attribute" element describes an attribute of a definition. It allows to
+     specify the tiles attribute name and its value. The tiles value can be
+     specified as an xml attribute, or in the body of the <put-attribute> tag.
+-->
+<!ELEMENT put-attribute ( (definition*) )>
+<!ATTLIST put-attribute     id               ID              #IMPLIED>
+<!--
+@attr name           The unique identifier for this put-attribute.
+-->
+<!ATTLIST put-attribute     name             CDATA           #REQUIRED>
+<!--
+@attr type           The type of the value. Can be: string, template or definition.
+                     By default, no type is associated to a value. If a type is
+                     associated, it will be used as a hint to process the value
+                     when the attribute will be used in the inserted tiles.
+-->
+<!ATTLIST put-attribute     type             %ContentType;   #IMPLIED>
+<!--
+@attr value          The value associated to this tiles attribute. The value should
+                     be specified with this tag attribute, or in the body of the tag.
+-->
+<!ATTLIST put-attribute     value            CDATA           #IMPLIED>
+<!--
+@attr expression     The expression associated to this tiles attribute. This
+           attribute will be ignored if value is specified.
+
+-->
+<!ATTLIST put-attribute     expression       CDATA           #IMPLIED>
+<!--
+@attr role           Security role name that is allowed access to this attribute
+                     object. The attribute is inserted only if the role name is
+                     allowed.
+-->
+<!ATTLIST put-attribute     role             CDATA            #IMPLIED>
+<!--
+@attr cascade        If true, the attribute will be cascaded to all inner
+                     definitions. By default, cascade is false.
+-->
+<!ATTLIST put-attribute     cascade          %Boolean;    #IMPLIED>
+
+
+<!-- The "put-list-attribute" element describes a list attribute of a definition. It allows to
+     specify an attribute that is a java List containing any kind of values. In
+     the config file, the list elements are specified by nested <add-attribute> or
+     <add-list-attribute>.
+-->
+<!ELEMENT put-list-attribute ( (add-attribute* | add-list-attribute*)+) >
+<!ATTLIST put-list-attribute id               ID              #IMPLIED>
+<!--
+@attr name           The unique identifier for this put attribute list.
+-->
+<!ATTLIST put-list-attribute name             CDATA           #REQUIRED>
+<!--
+@attr role           Security role name that is allowed access to this attribute
+                     object. The attribute is inserted only if the role name is
+                     allowed.
+-->
+<!ATTLIST put-list-attribute role             CDATA            #IMPLIED>
+<!--
+@attr inherit        If true, the attribute will put the elements of the attribute
+                     with the same name of the parent definition before the ones
+                     specified here. By default, it is 'false'.
+-->
+<!ATTLIST put-list-attribute inherit          %Boolean;        #IMPLIED>
+<!--
+@attr cascade        If true, the attribute will be cascaded to all inner
+                     definitions. By default, cascade is false.
+-->
+<!ATTLIST put-list-attribute cascade          %Boolean;        #IMPLIED>
+
+<!-- ========== Subordinate Elements ====================================== -->
+
+
+<!-- The "add-attribute" element describes an element of a list. It is similar to the
+     <put> element.
+-->
+<!ELEMENT add-attribute ( (definition*) )>
+<!ATTLIST add-attribute              id               ID              #IMPLIED>
+<!--
+@attr type           The type of the value. Can be: string, template or definition.
+                     By default, no type is associated to a value. If a type is
+                     associated, it will be used as a hint to process the value
+                     when the attribute will be used in the inserted tiles.
+-->
+<!ATTLIST add-attribute              type             %ContentType;   #IMPLIED>
+<!--
+@attr value          The value associated to this tiles attribute. The value should
+                     be specified with this tag attribute, or in the body of the tag.
+-->
+<!ATTLIST add-attribute              value            CDATA           #IMPLIED>
+<!--
+@attr expression     The expression associated to this tiles attribute. This
+           attribute will be ignored if value is specified.
+
+-->
+<!ATTLIST add-attribute              expression       CDATA           #IMPLIED>
+<!--
+@attr role           Security role name that is allowed access to this attribute
+                     object. The attribute will be added to the parent list
+                     anyway. It is delegated to the user of this attribute to
+                     use it or not depending on the role of the user.
+-->
+<!ATTLIST add-attribute              role             CDATA            #IMPLIED>
+
+<!-- The "add-list-attribute" element describes a list attribute subordinate to another
+     list attribute. It allows to specify an attribute value that is a java List
+     containing any kind of values. In the config file, the list elements are specified
+     by nested <add-attribute> or <add-list-attribute>.
+-->
+<!ELEMENT add-list-attribute ( (add-attribute* | add-list-attribute*)+) >
+<!ATTLIST add-list-attribute id               ID              #IMPLIED>
+<!--
+@attr role           Security role name that is allowed access to this attribute
+                     object. The attribute will be added to the parent list
+                     anyway. It is delegated to the user of this attribute to
+                     use it or not depending on the role of the user.
+-->
+<!ATTLIST add-list-attribute role             CDATA            #IMPLIED>
diff --git a/Java-base/tiles/src/tiles-core/src/site/site.xml b/Java-base/tiles/src/tiles-core/src/site/site.xml
new file mode 100644
index 000000000..6cf638680
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/site/site.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<project name="Apache Tiles - Core Library">
+     <skin>
+        <groupId>org.apache.maven.skins</groupId>
+        <artifactId>maven-fluido-skin</artifactId>
+        <version>1.3.0</version>
+     </skin>
+     <custom>
+        <fluidoSkin>
+        <topBarEnabled>true</topBarEnabled>
+        <sideBarEnabled>false</sideBarEnabled>
+        <searchEnabled>true</searchEnabled>
+        <gitHub>
+            <projectId>apache/tiles</projectId>
+            <ribbonOrientation>right</ribbonOrientation>
+            <ribbonColor>darkblue</ribbonColor>
+        </gitHub>
+        </fluidoSkin>
+     </custom>
+    <bannerLeft>
+        <name>Apache Tiles&#8482;</name>
+        <src>http://tiles.apache.org/images/logo.png</src>
+        <href>http://tiles.apache.org</href>
+    </bannerLeft>
+    <bannerRight>
+        <name>Apache Software Foundation</name>
+        <src>http://struts.apache.org/images/asf-logo.gif</src>
+        <href>http://www.apache.org</href>
+    </bannerRight>
+    <body>
+
+        <menu name="Apache Tiles&#8482;">
+            <item
+                   name="Welcome"
+                   href="../../index.html"/>
+            <item
+                    name="Tiles 3.0.x"
+                    href="../../framework/index.html"/>
+            <item
+                    name="Autotag 1.0.x"
+                    href="../../tiles-autotag/index.html"/>
+            <item
+                    name="Request 1.0.x"
+                    href="../../tiles-request/index.html"/>
+            <item
+                   name="Security bulletins"
+                   href="../security/index.html"/>
+            <item
+                   name="Download"
+                   href="http://tiles.apache.org/download.html"/>
+        </menu>
+
+        <menu ref="modules" />
+        <menu ref="reports" />
+
+        <footer>
+            <div class="row span12">
+                Apache Tiles, Tiles, Apache, the Apache feather logo, and the Apache Tiles
+                project logos are trademarks of The Apache Software Foundation.
+            </div>
+        </footer>
+    </body>
+</project>
diff --git a/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/context/TilesRequestContextHolderTest.java b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/context/TilesRequestContextHolderTest.java
new file mode 100644
index 000000000..7547f0d0b
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/context/TilesRequestContextHolderTest.java
@@ -0,0 +1,51 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.context;
+
+import static org.junit.Assert.*;
+import static org.easymock.EasyMock.*;
+
+import org.apache.tiles.request.Request;
+import org.junit.Test;
+
+/**
+ * Tests {@link TilesRequestContextHolderTest}.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public class TilesRequestContextHolderTest {
+
+    /**
+     * Test method for {@link TilesRequestContextHolder#setTilesRequestContext(Request)}.
+     */
+    @Test
+    public void testSetTilesRequestContext() {
+        Request request = createMock(Request.class);
+
+        replay(request);
+        TilesRequestContextHolder holder = new TilesRequestContextHolder();
+        holder.setTilesRequestContext(request);
+        assertSame(request, holder.getTilesRequestContext());
+        verify(request);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/DefinitionsFactoryExceptionTest.java b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/DefinitionsFactoryExceptionTest.java
new file mode 100644
index 000000000..fbd48c263
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/DefinitionsFactoryExceptionTest.java
@@ -0,0 +1,77 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+/**
+ * Tests {@link DefinitionsFactoryException}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class DefinitionsFactoryExceptionTest {
+
+    /**
+     * Test method for {@link DefinitionsFactoryException#DefinitionsFactoryException()}.
+     */
+    @Test
+    public void testDefinitionsFactoryException() {
+        DefinitionsFactoryException exception = new DefinitionsFactoryException();
+        assertNull(exception.getMessage());
+        assertNull(exception.getCause());
+    }
+
+    /**
+     * Test method for {@link DefinitionsFactoryException#DefinitionsFactoryException(java.lang.String)}.
+     */
+    @Test
+    public void testDefinitionsFactoryExceptionString() {
+        DefinitionsFactoryException exception = new DefinitionsFactoryException("my message");
+        assertEquals("my message", exception.getMessage());
+        assertNull(exception.getCause());
+    }
+
+    /**
+     * Test method for {@link DefinitionsFactoryException#DefinitionsFactoryException(java.lang.Throwable)}.
+     */
+    @Test
+    public void testDefinitionsFactoryExceptionThrowable() {
+        Throwable cause = new Throwable();
+        DefinitionsFactoryException exception = new DefinitionsFactoryException(cause);
+        assertEquals(cause.toString(), exception.getMessage());
+        assertEquals(cause, exception.getCause());
+    }
+
+    /**
+     * Test method for {@link DefinitionsFactoryException#DefinitionsFactoryException(String, Throwable)}.
+     */
+    @Test
+    public void testDefinitionsFactoryExceptionStringThrowable() {
+        Throwable cause = new Throwable();
+        DefinitionsFactoryException exception = new DefinitionsFactoryException("my message", cause);
+        assertEquals("my message", exception.getMessage());
+        assertEquals(cause, exception.getCause());
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/FactoryNotFoundExceptitonTest.java b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/FactoryNotFoundExceptitonTest.java
new file mode 100644
index 000000000..e7742885a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/FactoryNotFoundExceptitonTest.java
@@ -0,0 +1,77 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+/**
+ * Tests {@link FactoryNotFoundException}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class FactoryNotFoundExceptitonTest {
+
+    /**
+     * Test method for {@link FactoryNotFoundException#FactoryNotFoundException()}.
+     */
+    @Test
+    public void testFactoryNotFoundException() {
+        FactoryNotFoundException exception = new FactoryNotFoundException();
+        assertNull(exception.getMessage());
+        assertNull(exception.getCause());
+    }
+
+    /**
+     * Test method for {@link FactoryNotFoundException#FactoryNotFoundException(java.lang.String)}.
+     */
+    @Test
+    public void testFactoryNotFoundExceptionString() {
+        FactoryNotFoundException exception = new FactoryNotFoundException("my message");
+        assertEquals("my message", exception.getMessage());
+        assertNull(exception.getCause());
+    }
+
+    /**
+     * Test method for {@link FactoryNotFoundException#FactoryNotFoundException(java.lang.Throwable)}.
+     */
+    @Test
+    public void testFactoryNotFoundExceptionThrowable() {
+        Throwable cause = new Throwable();
+        FactoryNotFoundException exception = new FactoryNotFoundException(cause);
+        assertEquals(cause.toString(), exception.getMessage());
+        assertEquals(cause, exception.getCause());
+    }
+
+    /**
+     * Test method for {@link FactoryNotFoundException#FactoryNotFoundException(java.lang.String, java.lang.Throwable)}.
+     */
+    @Test
+    public void testFactoryNotFoundExceptionStringThrowable() {
+        Throwable cause = new Throwable();
+        FactoryNotFoundException exception = new FactoryNotFoundException("my message", cause);
+        assertEquals("my message", exception.getMessage());
+        assertEquals(cause, exception.getCause());
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/LocaleDefinitionsFactoryTest.java b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/LocaleDefinitionsFactoryTest.java
new file mode 100644
index 000000000..f2bc63d83
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/LocaleDefinitionsFactoryTest.java
@@ -0,0 +1,108 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition;
+
+import static org.easymock.EasyMock.*;
+import static org.easymock.classextension.EasyMock.*;
+import static org.junit.Assert.*;
+
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.Definition;
+import org.apache.tiles.definition.dao.DefinitionDAO;
+import org.apache.tiles.locale.LocaleResolver;
+import org.apache.tiles.request.Request;
+import org.junit.Test;
+
+/**
+ * Tests {@link LocaleDefinitionsFactory}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class LocaleDefinitionsFactoryTest {
+
+    /**
+     * Test method for {@link LocaleDefinitionsFactory#getDefinition(String, Request)}.
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testGetDefinition() {
+        DefinitionDAO<Locale> dao = createMock(DefinitionDAO.class);
+        LocaleResolver localeResolver = createMock(LocaleResolver.class);
+        Request request = createMock(Request.class);
+        Attribute templateAttribute = Attribute.createTemplateAttribute("/mytemplate.jsp");
+        Definition definition = new Definition("myDefinition", null, null);
+        definition.setExtends("anotherDefinition");
+        Map<String, Attribute> attributes = new HashMap<String, Attribute>();
+        attributes.put("first", new Attribute("myValue"));
+        Definition anotherDefinition = new Definition("anotherDefinition", templateAttribute, attributes);
+        Locale locale = Locale.ITALY;
+
+        expect(localeResolver.resolveLocale(request)).andReturn(locale);
+        expect(dao.getDefinition("myDefinition", locale)).andReturn(definition);
+        expect(dao.getDefinition("anotherDefinition", locale)).andReturn(anotherDefinition);
+
+        LocaleDefinitionsFactory factory = new LocaleDefinitionsFactory();
+
+        replay(dao, localeResolver, request);
+        factory.setDefinitionDAO(dao);
+        factory.setLocaleResolver(localeResolver);
+        Definition realDefinition = new Definition(definition);
+        realDefinition.inherit(anotherDefinition);
+        assertEquals(realDefinition, factory.getDefinition("myDefinition", request));
+        verify(dao, localeResolver, request);
+    }
+
+    /**
+     * Test method for {@link LocaleDefinitionsFactory#getDefinition(String, Request)}.
+     */
+    @SuppressWarnings("unchecked")
+    @Test(expected = NoSuchDefinitionException.class)
+    public void testGetDefinitionNoParent() {
+        DefinitionDAO<Locale> dao = createMock(DefinitionDAO.class);
+        LocaleResolver localeResolver = createMock(LocaleResolver.class);
+        Request request = createMock(Request.class);
+        Definition definition = new Definition("myDefinition", null, null);
+        definition.setExtends("anotherDefinition");
+        Map<String, Attribute> attributes = new HashMap<String, Attribute>();
+        attributes.put("first", new Attribute("myValue"));
+        Locale locale = Locale.ITALY;
+
+        expect(localeResolver.resolveLocale(request)).andReturn(locale);
+        expect(dao.getDefinition("myDefinition", locale)).andReturn(definition);
+        expect(dao.getDefinition("anotherDefinition", locale)).andReturn(null);
+
+        LocaleDefinitionsFactory factory = new LocaleDefinitionsFactory();
+
+        replay(dao, localeResolver, request);
+        try {
+            factory.setDefinitionDAO(dao);
+            factory.setLocaleResolver(localeResolver);
+            factory.getDefinition("myDefinition", request);
+        } finally {
+            verify(dao, localeResolver, request);
+        }
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/MockDefinitionsReader.java b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/MockDefinitionsReader.java
new file mode 100644
index 000000000..6c91d7dca
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/MockDefinitionsReader.java
@@ -0,0 +1,69 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.apache.tiles.Definition;
+
+/**
+ * Mock Defintions Reader implementation.  Stubs out all functionality.
+ *
+ * @version $Rev$ $Date$
+ */
+public class MockDefinitionsReader implements DefinitionsReader {
+
+    /**
+     * Hokey way to verify that this was created.
+     */
+    private static int instanceCount = 0;
+
+    /**
+     * Hokey way to verify that this class was created.
+     *
+     * @return The number of created instances.
+     */
+    public static int getInstanceCount() {
+        return instanceCount;
+    }
+
+    /** Creates a new instance of MockDefinitionsReader. */
+    public MockDefinitionsReader() {
+        instanceCount++;
+    }
+
+    /**
+     * Reads <code>{@link Definition}</code> objects from a source.
+     *
+     * Implementations should publish what type of source object is expected.
+     *
+     * @param source The source from which definitions will be read.
+     * @return a Map of <code>Definition</code> objects read from
+     *  the source.
+     * @throws org.apache.tiles.definition.DefinitionsFactoryException if the source is invalid or
+     *  an error occurs when reading definitions.
+     */
+    public Map<String, Definition> read(Object source) {
+        return new LinkedHashMap<String, Definition>();
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/NoSuchDefinitionExceptionTest.java b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/NoSuchDefinitionExceptionTest.java
new file mode 100644
index 000000000..e2130d21e
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/NoSuchDefinitionExceptionTest.java
@@ -0,0 +1,77 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+/**
+ * Tests {@link NoSuchDefinitionException}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class NoSuchDefinitionExceptionTest {
+
+    /**
+     * Test method for {@link NoSuchDefinitionException#NoSuchDefinitionException()}.
+     */
+    @Test
+    public void testNoSuchDefinitionException() {
+        NoSuchDefinitionException exception = new NoSuchDefinitionException();
+        assertNull(exception.getMessage());
+        assertNull(exception.getCause());
+    }
+
+    /**
+     * Test method for {@link NoSuchDefinitionException#NoSuchDefinitionException(java.lang.String)}.
+     */
+    @Test
+    public void testNoSuchDefinitionExceptionString() {
+        NoSuchDefinitionException exception = new NoSuchDefinitionException("my message");
+        assertEquals("my message", exception.getMessage());
+        assertNull(exception.getCause());
+    }
+
+    /**
+     * Test method for {@link NoSuchDefinitionException#NoSuchDefinitionException(java.lang.Throwable)}.
+     */
+    @Test
+    public void testNoSuchDefinitionExceptionThrowable() {
+        Throwable cause = new Throwable();
+        NoSuchDefinitionException exception = new NoSuchDefinitionException(cause);
+        assertEquals(cause.toString(), exception.getMessage());
+        assertEquals(cause, exception.getCause());
+    }
+
+    /**
+     * Test method for {@link NoSuchDefinitionException#NoSuchDefinitionException(String, Throwable)}.
+     */
+    @Test
+    public void testNoSuchDefinitionExceptionStringThrowable() {
+        Throwable cause = new Throwable();
+        NoSuchDefinitionException exception = new NoSuchDefinitionException("my message", cause);
+        assertEquals("my message", exception.getMessage());
+        assertEquals(cause, exception.getCause());
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/UnresolvingLocaleDefinitionsFactoryTest.java b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/UnresolvingLocaleDefinitionsFactoryTest.java
new file mode 100644
index 000000000..918ac096b
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/UnresolvingLocaleDefinitionsFactoryTest.java
@@ -0,0 +1,66 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition;
+
+import static org.easymock.EasyMock.*;
+import static org.easymock.classextension.EasyMock.*;
+import static org.junit.Assert.*;
+
+import java.util.Locale;
+
+import org.apache.tiles.Definition;
+import org.apache.tiles.definition.dao.DefinitionDAO;
+import org.apache.tiles.locale.LocaleResolver;
+import org.apache.tiles.request.Request;
+import org.junit.Test;
+
+/**
+ * Tests {@link UnresolvingLocaleDefinitionsFactory}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class UnresolvingLocaleDefinitionsFactoryTest {
+
+    /**
+     * Test method for {@link UnresolvingLocaleDefinitionsFactory#getDefinition(String, Request)}.
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testGetDefinition() {
+        DefinitionDAO<Locale> dao = createMock(DefinitionDAO.class);
+        LocaleResolver localeResolver = createMock(LocaleResolver.class);
+        UnresolvingLocaleDefinitionsFactory factory = new UnresolvingLocaleDefinitionsFactory();
+        Request request = createMock(Request.class);
+        Definition definition = createMock(Definition.class);
+        Locale locale = Locale.ITALY;
+
+        expect(localeResolver.resolveLocale(request)).andReturn(locale);
+        expect(dao.getDefinition("myDefinition", locale)).andReturn(definition);
+
+        replay(dao, localeResolver, request, definition);
+        factory.setDefinitionDAO(dao);
+        factory.setLocaleResolver(localeResolver);
+        assertEquals(definition, factory.getDefinition("myDefinition", request));
+        verify(dao, localeResolver, request, definition);
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/dao/BaseLocaleUrlDefinitionDAOTest.java b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/dao/BaseLocaleUrlDefinitionDAOTest.java
new file mode 100644
index 000000000..91412e2e6
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/dao/BaseLocaleUrlDefinitionDAOTest.java
@@ -0,0 +1,184 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.definition.dao;
+
+import static org.easymock.EasyMock.*;
+import static org.easymock.classextension.EasyMock.*;
+import static org.junit.Assert.*;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.Definition;
+import org.apache.tiles.definition.DefinitionsReader;
+import org.apache.tiles.definition.RefreshMonitor;
+import org.apache.tiles.definition.digester.DigesterDefinitionsReader;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.ApplicationResource;
+import org.apache.tiles.request.Request;
+import org.apache.tiles.request.locale.PostfixedApplicationResource;
+import org.apache.tiles.request.locale.URLApplicationResource;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests {@link BaseLocaleUrlDefinitionDAO}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class BaseLocaleUrlDefinitionDAOTest {
+
+    private static final class MutableApplicationResource extends PostfixedApplicationResource {
+        private long lastModified = System.currentTimeMillis();
+        private String xml = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n"
+                + "<!DOCTYPE tiles-definitions PUBLIC "
+                + "\"-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN\" "
+                + "\"http://tiles.apache.org/dtds/tiles-config_3_0.dtd\">\n\n" + "<tiles-definitions>"
+                + "<definition name=\"rewrite.test\" template=\"/test.jsp\">"
+                + "<put-attribute name=\"testparm\" value=\"testval\"/>" + "</definition>" //
+                + "</tiles-definitions>";
+
+        private MutableApplicationResource(String localePath) {
+            super(localePath);
+        }
+
+        public void modify(String xml) {
+            lastModified = System.currentTimeMillis();
+            this.xml = xml;
+        }
+
+        @Override
+        public long getLastModified() {
+            return lastModified;
+        }
+
+        @Override
+        public InputStream getInputStream() throws IOException {
+
+            return new ByteArrayInputStream(xml.getBytes("ISO-8859-1"));
+        }
+    }
+
+    /**
+     * The time (in milliseconds) to wait to be sure that the system updates the
+     * modify date of a file.
+     */
+    private static final int SLEEP_MILLIS = 2000;
+
+    /**
+     * The dao to test.
+     */
+    private ApplicationContext applicationContext;
+
+    private BaseLocaleUrlDefinitionDAO dao;
+    private MutableApplicationResource resource;
+
+    /**
+     * Sets up the test.
+     * @throws IOException
+     */
+    @Before
+    public void setUp() throws IOException {
+        resource = new MutableApplicationResource("org/apache/tiles/config/temp-defs.xml");
+        applicationContext = createMock(ApplicationContext.class);
+        expect(applicationContext.getResource("org/apache/tiles/config/temp-defs.xml")).andReturn(resource).anyTimes();
+        replay(applicationContext);
+        dao = createMockBuilder(BaseLocaleUrlDefinitionDAO.class).withConstructor(applicationContext).createMock();
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.definition.dao.BaseLocaleUrlDefinitionDAO#refreshRequired()}.
+     * @throws URISyntaxException If something goes wrong.
+     * @throws IOException If something goes wrong.
+     * @throws InterruptedException If something goes wrong.
+     */
+    @Test
+    public void testRefreshRequired() throws URISyntaxException, IOException, InterruptedException {
+        // Set up multiple data sources.
+        Map<String, Attribute> attribs = new HashMap<String, Attribute>();
+        attribs.put("testparm", new Attribute("testval"));
+        Definition rewriteTest = new Definition("rewrite.test", Attribute.createTemplateAttribute("/test.jsp"), attribs);
+        expect(dao.getDefinition("rewrite.test", null)).andReturn(rewriteTest);
+
+        replay(dao);
+
+        List<ApplicationResource> sources = new ArrayList<ApplicationResource>();
+        sources.add(resource);
+        dao.setSources(sources);
+        DefinitionsReader reader = new DigesterDefinitionsReader();
+        dao.setReader(reader);
+
+        Request context = createMock(Request.class);
+        expect(context.getContext("session")).andReturn(new HashMap<String, Object>()).anyTimes();
+        expect(context.getRequestLocale()).andReturn(null).anyTimes();
+        replay(context);
+
+        Definition definition = dao.getDefinition("rewrite.test", null);
+        assertNotNull("rewrite.test definition not found.", definition);
+        assertEquals("Incorrect initial template value", "/test.jsp", definition.getTemplateAttribute().getValue());
+
+        RefreshMonitor reloadable = dao;
+        dao.loadDefinitionsFromResource(resource);
+        assertEquals("Factory should be fresh.", false, reloadable.refreshRequired());
+
+        // Make sure the system actually updates the timestamp.
+        Thread.sleep(SLEEP_MILLIS);
+
+        // Set up multiple data sources.
+        resource.modify("<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n" + "<!DOCTYPE tiles-definitions PUBLIC "
+                + "\"-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN\" "
+                + "\"http://tiles.apache.org/dtds/tiles-config_3_0.dtd\">\n\n" + "<tiles-definitions>"
+                + "<definition name=\"rewrite.test\" template=\"/newtest.jsp\">"
+                + "<put-attribute name=\"testparm\" value=\"testval\"/>" + "</definition>" //
+                + "</tiles-definitions>");
+
+        assertEquals("Factory should be stale.", true, reloadable.refreshRequired());
+
+        verify(context, dao);
+    }
+
+    /**
+     * Test method for {@link BaseLocaleUrlDefinitionDAO#loadDefinitionsFromURL(URL)}.
+     * @throws MalformedURLException If something goes wrong.
+     */
+    @Test
+    public void testLoadDefinitionsFromURLFileNotFound() throws MalformedURLException {
+        URLApplicationResource resource = new URLApplicationResource("/hello/there.txt", new URL(
+                "file:///hello/there.txt"));
+        replay(dao);
+        DefinitionsReader reader = createMock(DefinitionsReader.class);
+        replay(reader);
+
+        dao.setReader(reader);
+        assertNull(dao.loadDefinitionsFromResource(resource));
+        verify(dao, reader);
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/dao/CachingLocaleUrlDefinitionDAOTest.java b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/dao/CachingLocaleUrlDefinitionDAOTest.java
new file mode 100644
index 000000000..c7eb12f7d
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/dao/CachingLocaleUrlDefinitionDAOTest.java
@@ -0,0 +1,382 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition.dao;
+
+import static org.easymock.EasyMock.*;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import junit.framework.TestCase;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.Definition;
+import org.apache.tiles.ListAttribute;
+import org.apache.tiles.definition.DefinitionsReader;
+import org.apache.tiles.definition.MockDefinitionsReader;
+import org.apache.tiles.definition.digester.DigesterDefinitionsReader;
+import org.apache.tiles.definition.pattern.BasicPatternDefinitionResolver;
+import org.apache.tiles.definition.pattern.PatternDefinitionResolver;
+import org.apache.tiles.definition.pattern.wildcard.WildcardDefinitionPatternMatcherFactory;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.ApplicationResource;
+import org.apache.tiles.request.locale.URLApplicationResource;
+
+/**
+ * Tests {@link CachingLocaleUrlDefinitionDAO}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class CachingLocaleUrlDefinitionDAOTest extends TestCase {
+
+    /**
+     * The object to test.
+     */
+    private CachingLocaleUrlDefinitionDAO definitionDao;
+
+    private ApplicationContext applicationContext;
+
+    private ApplicationResource url1;
+
+    private ApplicationResource url2;
+
+    private ApplicationResource url3;
+
+    private ApplicationResource urlWildcard;
+
+    private ApplicationResource url21;
+
+    private ApplicationResource setupUrl(String filename, Locale... locales) throws IOException {
+        ApplicationResource url = new URLApplicationResource("org/apache/tiles/config/" + filename + ".xml", this
+                .getClass().getClassLoader().getResource("org/apache/tiles/config/" + filename + ".xml"));
+        assertNotNull("Could not load " + filename + " file.", url);
+        expect(applicationContext.getResource(url.getLocalePath())).andReturn(url).anyTimes();
+        expect(applicationContext.getResource(url, Locale.ROOT)).andReturn(url).anyTimes();
+        Map<Locale, ApplicationResource> localeResources = new HashMap<Locale, ApplicationResource>();
+        for (Locale locale : locales) {
+            ApplicationResource urlLocale = new URLApplicationResource("org/apache/tiles/config/" + filename + "_"
+                    + locale.toString() + ".xml", this.getClass().getClassLoader()
+                    .getResource("org/apache/tiles/config/" + filename + "_" + locale.toString() + ".xml"));
+            assertNotNull("Could not load " + filename + "_" + locale.toString() + " file.", urlLocale);
+            localeResources.put(locale, urlLocale);
+        }
+        for (Locale locale : new Locale[] { Locale.CANADA_FRENCH, Locale.FRENCH, Locale.US, Locale.ENGLISH,
+                Locale.CHINA, Locale.CHINESE, Locale.ITALY, Locale.ITALIAN }) {
+            ApplicationResource urlLocale = localeResources.get(locale);
+            expect(applicationContext.getResource(url, locale)).andReturn(urlLocale).anyTimes();
+        }
+        return url;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        applicationContext = createMock(ApplicationContext.class);
+        url1 = setupUrl("defs1", Locale.FRENCH, Locale.CANADA_FRENCH, Locale.US);
+        url2 = setupUrl("defs2");
+        url3 = setupUrl("defs3");
+        urlWildcard = setupUrl("defs-wildcard");
+        url21 = setupUrl("tiles-defs-2.1", Locale.ITALIAN);
+        replay(applicationContext);
+        definitionDao = new CachingLocaleUrlDefinitionDAO(applicationContext);
+        WildcardDefinitionPatternMatcherFactory definitionPatternMatcherFactory =
+            new WildcardDefinitionPatternMatcherFactory();
+        PatternDefinitionResolver<Locale> definitionResolver = new BasicPatternDefinitionResolver<Locale>(
+                definitionPatternMatcherFactory,
+                definitionPatternMatcherFactory);
+        definitionDao.setPatternDefinitionResolver(definitionResolver);
+    }
+
+    /**
+     * Tests {@link LocaleUrlDefinitionDAO#getDefinition(String, Locale)}.
+     */
+    public void testGetDefinition() {
+        List<ApplicationResource> sourceURLs = new ArrayList<ApplicationResource>();
+        sourceURLs.add(url1);
+        sourceURLs.add(url2);
+        sourceURLs.add(url3);
+        definitionDao.setSources(sourceURLs);
+        DefinitionsReader reader = new DigesterDefinitionsReader();
+        definitionDao.setReader(reader);
+
+        assertNotNull("test.def1 definition not found.", definitionDao
+                .getDefinition("test.def1", null));
+        assertNotNull("test.def2 definition not found.", definitionDao
+                .getDefinition("test.def2", null));
+        assertNotNull("test.def3 definition not found.", definitionDao
+                .getDefinition("test.def3", null));
+        assertNotNull("test.common definition not found.", definitionDao
+                .getDefinition("test.common", null));
+        assertNotNull("test.common definition in US locale not found.",
+                definitionDao.getDefinition("test.common", Locale.US));
+        assertNotNull("test.common definition in FRENCH locale not found.",
+                definitionDao.getDefinition("test.common", Locale.FRENCH));
+        assertNotNull("test.common definition in CHINA locale not found.",
+                definitionDao.getDefinition("test.common", Locale.CHINA));
+        assertNotNull(
+                "test.common.french definition in FRENCH locale not found.",
+                definitionDao.getDefinition("test.common.french",
+                        Locale.FRENCH));
+        assertNotNull(
+                "test.common.french definition in CANADA_FRENCH locale not found.",
+                definitionDao.getDefinition("test.common.french",
+                        Locale.CANADA_FRENCH));
+        assertNotNull("test.def.toextend definition not found.", definitionDao
+                .getDefinition("test.def.toextend", null));
+        assertNotNull("test.def.overridden definition not found.",
+                definitionDao.getDefinition("test.def.overridden", null));
+        assertNotNull(
+                "test.def.overridden definition in FRENCH locale not found.",
+                definitionDao.getDefinition("test.def.overridden",
+                        Locale.FRENCH));
+
+        assertEquals("Incorrect default country value", "default",
+                definitionDao.getDefinition("test.def1", null).getAttribute(
+                        "country").getValue());
+        assertEquals("Incorrect US country value", "US", definitionDao
+                .getDefinition("test.def1", Locale.US).getAttribute("country")
+                .getValue());
+        assertEquals("Incorrect France country value", "France", definitionDao
+                .getDefinition("test.def1", Locale.FRENCH).getAttribute(
+                        "country").getValue());
+        assertEquals("Incorrect Chinese country value (should be default)",
+                "default", definitionDao.getDefinition("test.def1",
+                        Locale.CHINA).getAttribute("country").getValue());
+        assertEquals("Incorrect default country value", "default",
+                definitionDao.getDefinition("test.def.overridden", null)
+                        .getAttribute("country").getValue());
+        assertEquals("Incorrect default title value",
+                "Definition to be overridden", definitionDao.getDefinition(
+                        "test.def.overridden", null).getAttribute("title")
+                        .getValue());
+        assertEquals("Incorrect France country value", "France", definitionDao
+                .getDefinition("test.def.overridden", Locale.FRENCH)
+                .getAttribute("country").getValue());
+        assertNull("Definition in French not found", definitionDao
+                .getDefinition("test.def.overridden", Locale.FRENCH)
+                .getAttribute("title"));
+    }
+
+    /**
+     * Tests {@link LocaleUrlDefinitionDAO#getDefinitions(Locale)}.
+     */
+    public void testGetDefinitions() {
+        List<ApplicationResource> sourceURLs = new ArrayList<ApplicationResource>();
+        sourceURLs.add(url1);
+        sourceURLs.add(url2);
+        sourceURLs.add(url3);
+        definitionDao.setSources(sourceURLs);
+        DefinitionsReader reader = new DigesterDefinitionsReader();
+        definitionDao.setReader(reader);
+
+        Map<String, Definition> defaultDefinitions = definitionDao
+                .getDefinitions(null);
+        Map<String, Definition> usDefinitions = definitionDao
+                .getDefinitions(Locale.US);
+        Map<String, Definition> frenchDefinitions = definitionDao
+                .getDefinitions(Locale.FRENCH);
+        Map<String, Definition> chinaDefinitions = definitionDao
+                .getDefinitions(Locale.CHINA);
+        Map<String, Definition> canadaFrenchDefinitions = definitionDao
+                .getDefinitions(Locale.CANADA_FRENCH);
+
+        assertNotNull("test.def1 definition not found.", defaultDefinitions
+                .get("test.def1"));
+        assertNotNull("test.def2 definition not found.", defaultDefinitions
+                .get("test.def2"));
+        assertNotNull("test.def3 definition not found.", defaultDefinitions
+                .get("test.def3"));
+        assertNotNull("test.common definition not found.", defaultDefinitions
+                .get("test.common"));
+        assertNotNull("test.common definition in US locale not found.",
+                usDefinitions.get("test.common"));
+        assertNotNull("test.common definition in FRENCH locale not found.",
+                frenchDefinitions.get("test.common"));
+        assertNotNull("test.common definition in CHINA locale not found.",
+                chinaDefinitions.get("test.common"));
+        assertNotNull(
+                "test.common.french definition in FRENCH locale not found.",
+                frenchDefinitions.get("test.common.french"));
+        assertNotNull(
+                "test.common.french definition in CANADA_FRENCH locale not found.",
+                canadaFrenchDefinitions.get("test.common.french"));
+        assertNotNull("test.def.toextend definition not found.",
+                defaultDefinitions.get("test.def.toextend"));
+        assertNotNull("test.def.overridden definition not found.",
+                defaultDefinitions.get("test.def.overridden"));
+        assertNotNull(
+                "test.def.overridden definition in FRENCH locale not found.",
+                frenchDefinitions.get("test.def.overridden"));
+
+        assertEquals("Incorrect default country value", "default",
+                defaultDefinitions.get("test.def1").getAttribute("country")
+                        .getValue());
+        assertEquals("Incorrect US country value", "US", usDefinitions.get(
+                "test.def1").getAttribute("country").getValue());
+        assertEquals("Incorrect France country value", "France",
+                frenchDefinitions.get("test.def1").getAttribute("country")
+                        .getValue());
+        assertEquals("Incorrect Chinese country value (should be default)",
+                "default", chinaDefinitions.get("test.def1").getAttribute(
+                        "country").getValue());
+        assertEquals("Incorrect default country value", "default",
+                defaultDefinitions.get("test.def.overridden").getAttribute(
+                        "country").getValue());
+        assertEquals("Incorrect default title value",
+                "Definition to be overridden", defaultDefinitions.get(
+                        "test.def.overridden").getAttribute("title").getValue());
+        assertEquals("Incorrect France country value", "France",
+                frenchDefinitions.get("test.def.overridden").getAttribute(
+                        "country").getValue());
+        assertNull("Definition in French not found", frenchDefinitions.get(
+                "test.def.overridden").getAttribute("title"));
+    }
+
+    /**
+     * Tests {@link LocaleUrlDefinitionDAO#setSources(List)}.
+     */
+    public void testSetSourceURLs() {
+        List<ApplicationResource> sourceURLs = new ArrayList<ApplicationResource>();
+        sourceURLs.add(url1);
+        sourceURLs.add(url2);
+        sourceURLs.add(url3);
+        definitionDao.setSources(sourceURLs);
+        assertEquals("The source URLs are not set correctly", sourceURLs,
+                definitionDao.sources);
+    }
+
+    /**
+     * Tests {@link LocaleUrlDefinitionDAO#setReader(DefinitionsReader)}.
+     */
+    public void testSetReader() {
+        DefinitionsReader reader = createMock(DefinitionsReader.class);
+        definitionDao.setReader(reader);
+        assertEquals("There reader has not been set correctly", reader,
+                definitionDao.reader);
+    }
+
+    /**
+     * Tests execution.
+     *
+     * @throws IOException If something goes wrong.
+     */
+    public void testInit() throws IOException {
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        Set<ApplicationResource> urlSet = new HashSet<ApplicationResource>();
+        urlSet.add(url1);
+        expect(applicationContext.getResources("/WEB-INF/tiles.xml"))
+                .andReturn(urlSet);
+        replay(applicationContext);
+        DefinitionsReader reader = new DigesterDefinitionsReader();
+        definitionDao.setReader(reader);
+        List<ApplicationResource> sourceURLs = new ArrayList<ApplicationResource>();
+        sourceURLs.add(url1);
+        definitionDao.setSources(sourceURLs);
+        assertEquals("The reader is not of the correct class",
+                DigesterDefinitionsReader.class, definitionDao.reader
+                        .getClass());
+        assertEquals("The source URLs are not correct", sourceURLs,
+                definitionDao.sources);
+        reset(applicationContext);
+
+        definitionDao.setReader(new MockDefinitionsReader());
+        assertEquals("The reader is not of the correct class",
+                MockDefinitionsReader.class, definitionDao.reader.getClass());
+        sourceURLs = new ArrayList<ApplicationResource>();
+        sourceURLs.add(url1);
+        sourceURLs.add(url2);
+        sourceURLs.add(url3);
+        definitionDao.setSources(sourceURLs);
+        assertEquals("The source URLs are not correct", sourceURLs,
+                definitionDao.sources);
+    }
+
+    /**
+     * Tests wildcard mappings.
+     */
+    public void testWildcardMapping() {
+        List<ApplicationResource> urls = new ArrayList<ApplicationResource>();
+        urls.add(urlWildcard);
+        definitionDao.setSources(urls);
+        definitionDao.setReader(new DigesterDefinitionsReader());
+
+        Definition definition = definitionDao.getDefinition("test.defName.subLayered", Locale.ITALY);
+        assertEquals("The template is not correct", "/testName.jsp", definition
+                .getTemplateAttribute().getValue());
+        assertEquals("The header attribute is not correct",
+                "/common/headerLayered.jsp", definition.getAttribute("header")
+                        .getValue());
+        definition = definitionDao.getDefinition("test.defName.subLayered", Locale.ITALIAN);
+        assertEquals("The template is not correct", "/testName.jsp", definition
+                .getTemplateAttribute().getValue());
+        assertEquals("The header attribute is not correct",
+                "/common/headerLayered.jsp", definition.getAttribute("header")
+                        .getValue());
+        definition = definitionDao.getDefinition("test.defName.subLayered", null);
+        assertEquals("The template is not correct", "/testName.jsp", definition
+                .getTemplateAttribute().getValue());
+        assertEquals("The header attribute is not correct",
+                "/common/headerLayered.jsp", definition.getAttribute("header")
+                        .getValue());
+        definition = definitionDao.getDefinition("test.defName.noAttribute", null);
+        assertEquals("/testName.jsp", definition.getTemplateAttribute().getValue());
+        assertEquals(null, definition.getLocalAttributeNames());
+        definition = definitionDao.getDefinition("test.def3", null);
+        assertNotNull("The simple definition is null", definition);
+
+        definition = definitionDao.getDefinition("test.extended.defName.subLayered", null);
+        assertEquals("test.defName.subLayered", definition.getExtends());
+        assertNull(definition.getTemplateAttribute().getValue());
+        assertEquals(1, definition.getLocalAttributeNames().size());
+        assertEquals("Overridden Title", definition.getAttribute("title").getValue());
+    }
+
+    /**
+     * Tests
+     * {@link ResolvingLocaleUrlDefinitionDAO#getDefinition(String, Locale)}
+     * when loading multiple files for a locale.
+     */
+    public void testListAttributeLocaleInheritance() {
+        List<ApplicationResource> urls = new ArrayList<ApplicationResource>();
+        urls.add(url21);
+        definitionDao.setSources(urls);
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        definitionDao.setReader(new DigesterDefinitionsReader());
+        replay(applicationContext);
+
+        Definition definition = definitionDao.getDefinition(
+                "test.inherit.list", Locale.ITALIAN);
+        ListAttribute listAttribute = (ListAttribute) definition
+                .getAttribute("list");
+        List<Attribute> attributes = listAttribute.getValue();
+        // It is right not to resolve inheritance in this DAO.
+        assertEquals(1, attributes.size());
+        verify(applicationContext);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/dao/LocaleUrlDefinitionDAOTest.java b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/dao/LocaleUrlDefinitionDAOTest.java
new file mode 100644
index 000000000..57bb86a8b
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/dao/LocaleUrlDefinitionDAOTest.java
@@ -0,0 +1,252 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition.dao;
+
+import static org.easymock.EasyMock.*;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+import org.apache.tiles.Definition;
+import org.apache.tiles.definition.DefinitionsReader;
+import org.apache.tiles.definition.MockDefinitionsReader;
+import org.apache.tiles.definition.digester.DigesterDefinitionsReader;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.ApplicationResource;
+import org.apache.tiles.request.locale.URLApplicationResource;
+
+/**
+ * Tests {@link LocaleUrlDefinitionDAO}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class LocaleUrlDefinitionDAOTest extends TestCase {
+
+    /**
+     * The object to test.
+     */
+    private LocaleUrlDefinitionDAO definitionDao;
+
+    private ApplicationContext applicationContext;
+
+    private ApplicationResource url1;
+
+    private ApplicationResource url2;
+
+    private ApplicationResource url3;
+
+    private ApplicationResource setupUrl(String filename, Locale... locales) throws IOException {
+        ApplicationResource url = new URLApplicationResource("org/apache/tiles/config/" + filename + ".xml", this
+                .getClass().getClassLoader().getResource("org/apache/tiles/config/" + filename + ".xml"));
+        assertNotNull("Could not load " + filename + " file.", url);
+        expect(applicationContext.getResource(url.getLocalePath())).andReturn(url).anyTimes();
+        expect(applicationContext.getResource(url, Locale.ROOT)).andReturn(url).anyTimes();
+        Map<Locale, ApplicationResource> localeResources = new HashMap<Locale, ApplicationResource>();
+        for (Locale locale : locales) {
+            ApplicationResource urlLocale = new URLApplicationResource("org/apache/tiles/config/" + filename + "_"
+                    + locale.toString() + ".xml", this.getClass().getClassLoader()
+                    .getResource("org/apache/tiles/config/" + filename + "_" + locale.toString() + ".xml"));
+            assertNotNull("Could not load " + filename + "_" + locale.toString() + " file.", urlLocale);
+            localeResources.put(locale, urlLocale);
+        }
+        for (Locale locale : new Locale[] { Locale.CANADA_FRENCH, Locale.FRENCH, Locale.US, Locale.ENGLISH,
+                Locale.CHINA, Locale.CHINESE }) {
+            ApplicationResource urlLocale = localeResources.get(locale);
+            expect(applicationContext.getResource(url, locale)).andReturn(urlLocale).anyTimes();
+        }
+        return url;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+
+        applicationContext = createMock(ApplicationContext.class);
+        url1 = setupUrl("defs1", Locale.FRENCH, Locale.CANADA_FRENCH, Locale.US);
+        url2 = setupUrl("defs2");
+        url3 = setupUrl("defs3");
+        replay(applicationContext);
+        definitionDao = new LocaleUrlDefinitionDAO(applicationContext);
+    }
+
+    /**
+     * Tests {@link LocaleUrlDefinitionDAO#getDefinition(String, Locale)}.
+     */
+    public void testGetDefinition() {
+        List<ApplicationResource> sourceURLs = new ArrayList<ApplicationResource>();
+        sourceURLs.add(url1);
+        sourceURLs.add(url2);
+        sourceURLs.add(url3);
+        definitionDao.setSources(sourceURLs);
+        DefinitionsReader reader = new DigesterDefinitionsReader();
+        definitionDao.setReader(reader);
+        assertNotNull("test.def1 definition not found.", definitionDao.getDefinition("test.def1", null));
+        assertNotNull("test.def2 definition not found.", definitionDao.getDefinition("test.def2", null));
+        assertNotNull("test.def3 definition not found.", definitionDao.getDefinition("test.def3", null));
+        assertNotNull("test.common definition not found.", definitionDao.getDefinition("test.common", null));
+        assertNotNull("test.common definition in US locale not found.",
+                definitionDao.getDefinition("test.common", Locale.US));
+        assertNotNull("test.common definition in FRENCH locale not found.",
+                definitionDao.getDefinition("test.common", Locale.FRENCH));
+        assertNotNull("test.common definition in CHINA locale not found.",
+                definitionDao.getDefinition("test.common", Locale.CHINA));
+        assertNotNull("test.common.french definition in FRENCH locale not found.",
+                definitionDao.getDefinition("test.common.french", Locale.FRENCH));
+        assertNotNull("test.common.french definition in CANADA_FRENCH locale not found.",
+                definitionDao.getDefinition("test.common.french", Locale.CANADA_FRENCH));
+        assertNotNull("test.def.toextend definition not found.", definitionDao.getDefinition("test.def.toextend", null));
+        assertNotNull("test.def.overridden definition not found.",
+                definitionDao.getDefinition("test.def.overridden", null));
+        assertNotNull("test.def.overridden definition in FRENCH locale not found.",
+                definitionDao.getDefinition("test.def.overridden", Locale.FRENCH));
+
+        assertEquals("Incorrect default country value", "default", definitionDao.getDefinition("test.def1", null)
+                .getAttribute("country").getValue());
+        assertEquals("Incorrect US country value", "US", definitionDao.getDefinition("test.def1", Locale.US)
+                .getAttribute("country").getValue());
+        assertEquals("Incorrect France country value", "France", definitionDao
+                .getDefinition("test.def1", Locale.FRENCH).getAttribute("country").getValue());
+        assertEquals("Incorrect Chinese country value (should be default)", "default",
+                definitionDao.getDefinition("test.def1", Locale.CHINA).getAttribute("country").getValue());
+        assertEquals("Incorrect default country value", "default",
+                definitionDao.getDefinition("test.def.overridden", null).getAttribute("country").getValue());
+        assertEquals("Incorrect default title value", "Definition to be overridden",
+                definitionDao.getDefinition("test.def.overridden", null).getAttribute("title").getValue());
+        assertEquals("Incorrect France country value", "France",
+                definitionDao.getDefinition("test.def.overridden", Locale.FRENCH).getAttribute("country").getValue());
+        assertNull("Definition in French not found", definitionDao.getDefinition("test.def.overridden", Locale.FRENCH)
+                .getAttribute("title"));
+    }
+
+    /**
+     * Tests {@link LocaleUrlDefinitionDAO#getDefinitions(Locale)}.
+     */
+    public void testGetDefinitions() {
+        List<ApplicationResource> sourceURLs = new ArrayList<ApplicationResource>();
+        sourceURLs.add(url1);
+        sourceURLs.add(url2);
+        sourceURLs.add(url3);
+        definitionDao.setSources(sourceURLs);
+        DefinitionsReader reader = new DigesterDefinitionsReader();
+        definitionDao.setReader(reader);
+
+        Map<String, Definition> defaultDefinitions = definitionDao.getDefinitions(null);
+        Map<String, Definition> usDefinitions = definitionDao.getDefinitions(Locale.US);
+        Map<String, Definition> frenchDefinitions = definitionDao.getDefinitions(Locale.FRENCH);
+        Map<String, Definition> chinaDefinitions = definitionDao.getDefinitions(Locale.CHINA);
+        Map<String, Definition> canadaFrenchDefinitions = definitionDao.getDefinitions(Locale.CANADA_FRENCH);
+
+        assertNotNull("test.def1 definition not found.", defaultDefinitions.get("test.def1"));
+        assertNotNull("test.def2 definition not found.", defaultDefinitions.get("test.def2"));
+        assertNotNull("test.def3 definition not found.", defaultDefinitions.get("test.def3"));
+        assertNotNull("test.common definition not found.", defaultDefinitions.get("test.common"));
+        assertNotNull("test.common definition in US locale not found.", usDefinitions.get("test.common"));
+        assertNotNull("test.common definition in FRENCH locale not found.", frenchDefinitions.get("test.common"));
+        assertNotNull("test.common definition in CHINA locale not found.", chinaDefinitions.get("test.common"));
+        assertNotNull("test.common.french definition in FRENCH locale not found.",
+                frenchDefinitions.get("test.common.french"));
+        assertNotNull("test.common.french definition in CANADA_FRENCH locale not found.",
+                canadaFrenchDefinitions.get("test.common.french"));
+        assertNotNull("test.def.toextend definition not found.", defaultDefinitions.get("test.def.toextend"));
+        assertNotNull("test.def.overridden definition not found.", defaultDefinitions.get("test.def.overridden"));
+        assertNotNull("test.def.overridden definition in FRENCH locale not found.",
+                frenchDefinitions.get("test.def.overridden"));
+
+        assertEquals("Incorrect default country value", "default",
+                defaultDefinitions.get("test.def1").getAttribute("country").getValue());
+        assertEquals("Incorrect US country value", "US", usDefinitions.get("test.def1").getAttribute("country")
+                .getValue());
+        assertEquals("Incorrect France country value", "France",
+                frenchDefinitions.get("test.def1").getAttribute("country").getValue());
+        assertEquals("Incorrect Chinese country value (should be default)", "default", chinaDefinitions
+                .get("test.def1").getAttribute("country").getValue());
+        assertEquals("Incorrect default country value", "default", defaultDefinitions.get("test.def.overridden")
+                .getAttribute("country").getValue());
+        assertEquals("Incorrect default title value", "Definition to be overridden",
+                defaultDefinitions.get("test.def.overridden").getAttribute("title").getValue());
+        assertEquals("Incorrect France country value", "France", frenchDefinitions.get("test.def.overridden")
+                .getAttribute("country").getValue());
+        assertNull("Definition in French not found", frenchDefinitions.get("test.def.overridden").getAttribute("title"));
+    }
+
+    /**
+     * Tests {@link LocaleUrlDefinitionDAO#setSources(List)}.
+     */
+    public void testSetSourceURLs() {
+        List<ApplicationResource> sourceURLs = new ArrayList<ApplicationResource>();
+        sourceURLs.add(url1);
+        sourceURLs.add(url2);
+        sourceURLs.add(url3);
+        definitionDao.setSources(sourceURLs);
+        assertEquals("The source URLs are not set correctly", sourceURLs, definitionDao.sources);
+    }
+
+    /**
+     * Tests {@link LocaleUrlDefinitionDAO#setReader(DefinitionsReader)}.
+     */
+    public void testSetReader() {
+        DefinitionsReader reader = createMock(DefinitionsReader.class);
+        replay(reader);
+        definitionDao.setReader(reader);
+        assertEquals("There reader has not been set correctly", reader, definitionDao.reader);
+        verify(reader);
+    }
+
+    /**
+     * Tests execution.
+     *
+     * @throws IOException If something goes wrong.
+     */
+    public void testInit() throws IOException {
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        List<ApplicationResource> urlSet = new ArrayList<ApplicationResource>();
+        urlSet.add(url1);
+        expect(applicationContext.getResources("/WEB-INF/tiles.xml")).andReturn(urlSet);
+        replay(applicationContext);
+        DefinitionsReader reader = new DigesterDefinitionsReader();
+        definitionDao.setReader(reader);
+        List<ApplicationResource> sourceURLs = new ArrayList<ApplicationResource>();
+        sourceURLs.add(url1);
+        definitionDao.setSources(sourceURLs);
+        assertEquals("The reader is not of the correct class", DigesterDefinitionsReader.class,
+                definitionDao.reader.getClass());
+        assertEquals("The source URLs are not correct", sourceURLs, definitionDao.sources);
+        reset(applicationContext);
+
+        definitionDao.setReader(new MockDefinitionsReader());
+        assertEquals("The reader is not of the correct class", MockDefinitionsReader.class,
+                definitionDao.reader.getClass());
+        sourceURLs = new ArrayList<ApplicationResource>();
+        sourceURLs.add(url1);
+        sourceURLs.add(url2);
+        sourceURLs.add(url3);
+        definitionDao.setSources(sourceURLs);
+        assertEquals("The source URLs are not correct", sourceURLs, definitionDao.sources);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/dao/ResolvingLocaleUrlDefinitionDAOTest.java b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/dao/ResolvingLocaleUrlDefinitionDAOTest.java
new file mode 100644
index 000000000..27642b363
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/dao/ResolvingLocaleUrlDefinitionDAOTest.java
@@ -0,0 +1,400 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition.dao;
+
+import static org.easymock.EasyMock.*;
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.Definition;
+import org.apache.tiles.ListAttribute;
+import org.apache.tiles.definition.DefinitionsReader;
+import org.apache.tiles.definition.MockDefinitionsReader;
+import org.apache.tiles.definition.NoSuchDefinitionException;
+import org.apache.tiles.definition.digester.DigesterDefinitionsReader;
+import org.apache.tiles.definition.pattern.BasicPatternDefinitionResolver;
+import org.apache.tiles.definition.pattern.PatternDefinitionResolver;
+import org.apache.tiles.definition.pattern.wildcard.WildcardDefinitionPatternMatcherFactory;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.ApplicationResource;
+import org.apache.tiles.request.locale.URLApplicationResource;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests {@link ResolvingLocaleUrlDefinitionDAO}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ResolvingLocaleUrlDefinitionDAOTest {
+
+    /**
+     * The number of attribute names.
+     */
+    private static final int ATTRIBUTE_NAMES_COUNT = 6;
+
+    /**
+     * The object to test.
+     */
+    private ResolvingLocaleUrlDefinitionDAO definitionDao;
+
+    private ApplicationContext applicationContext;
+
+    private ApplicationResource url1;
+    private ApplicationResource url2;
+    private ApplicationResource url3;
+    private ApplicationResource urlWildcard;
+    private ApplicationResource url21;
+    private ApplicationResource url513;
+
+    private ApplicationResource setupUrl(String filename, Locale... locales) throws IOException {
+        ApplicationResource url = new URLApplicationResource("org/apache/tiles/config/" + filename + ".xml", this
+                .getClass().getClassLoader().getResource("org/apache/tiles/config/" + filename + ".xml"));
+        assertNotNull("Could not load " + filename + " file.", url);
+        expect(applicationContext.getResource(url.getLocalePath())).andReturn(url).anyTimes();
+        expect(applicationContext.getResource(url, Locale.ROOT)).andReturn(url).anyTimes();
+        Map<Locale, ApplicationResource> localeResources = new HashMap<Locale, ApplicationResource>();
+        for (Locale locale : locales) {
+            ApplicationResource urlLocale = new URLApplicationResource("org/apache/tiles/config/" + filename + "_"
+                    + locale.toString() + ".xml", this.getClass().getClassLoader()
+                    .getResource("org/apache/tiles/config/" + filename + "_" + locale.toString() + ".xml"));
+            assertNotNull("Could not load " + filename + "_" + locale.toString() + " file.", urlLocale);
+            localeResources.put(locale, urlLocale);
+        }
+        for (Locale locale : new Locale[] { Locale.CANADA_FRENCH, Locale.FRENCH, Locale.US, Locale.ENGLISH,
+                Locale.CHINA, Locale.CHINESE, Locale.ITALY, Locale.ITALIAN, new Locale("es", "CO"), new Locale("es", "CA") }) {
+            ApplicationResource urlLocale = localeResources.get(locale);
+            expect(applicationContext.getResource(url, locale)).andReturn(urlLocale).anyTimes();
+        }
+        return url;
+    }
+
+    /** {@inheritDoc} */
+    @Before
+    public void setUp() throws IOException {
+        // Set up multiple data sources.
+        applicationContext = createMock(ApplicationContext.class);
+        url1 = setupUrl("defs1", Locale.FRENCH, Locale.CANADA_FRENCH, Locale.US);
+        url2 = setupUrl("defs2");
+        url3 = setupUrl("defs3");
+        urlWildcard = setupUrl("defs-wildcard");
+        url21 = setupUrl("tiles-defs-2.1", Locale.ITALIAN);
+        url513 = setupUrl("defs-tiles-513");
+        replay(applicationContext);
+
+        definitionDao = new ResolvingLocaleUrlDefinitionDAO(applicationContext);
+        WildcardDefinitionPatternMatcherFactory definitionPatternMatcherFactory = new WildcardDefinitionPatternMatcherFactory();
+        PatternDefinitionResolver<Locale> definitionResolver = new BasicPatternDefinitionResolver<Locale>(
+                definitionPatternMatcherFactory, definitionPatternMatcherFactory);
+        definitionDao.setPatternDefinitionResolver(definitionResolver);
+    }
+
+    /**
+     * Tests {@link LocaleUrlDefinitionDAO#getDefinition(String, Locale)}.
+     */
+    @Test
+    public void testGetDefinition() {
+        List<ApplicationResource> sourceURLs = new ArrayList<ApplicationResource>();
+        sourceURLs.add(url1);
+        sourceURLs.add(url2);
+        sourceURLs.add(url3);
+        definitionDao.setSources(sourceURLs);
+        DefinitionsReader reader = new DigesterDefinitionsReader();
+        definitionDao.setReader(reader);
+
+        assertNotNull("test.def1 definition not found.", definitionDao.getDefinition("test.def1", null));
+        assertNotNull("test.def2 definition not found.", definitionDao.getDefinition("test.def2", null));
+        assertNotNull("test.def3 definition not found.", definitionDao.getDefinition("test.def3", null));
+        assertNotNull("test.common definition not found.", definitionDao.getDefinition("test.common", null));
+        assertNotNull("test.common definition in US locale not found.",
+                definitionDao.getDefinition("test.common", Locale.US));
+        assertNotNull("test.common definition in FRENCH locale not found.",
+                definitionDao.getDefinition("test.common", Locale.FRENCH));
+        assertNotNull("test.common definition in CHINA locale not found.",
+                definitionDao.getDefinition("test.common", Locale.CHINA));
+        assertNotNull("test.common.french definition in FRENCH locale not found.",
+                definitionDao.getDefinition("test.common.french", Locale.FRENCH));
+        assertNotNull("test.common.french definition in CANADA_FRENCH locale not found.",
+                definitionDao.getDefinition("test.common.french", Locale.CANADA_FRENCH));
+        assertNotNull("test.def.toextend definition not found.", definitionDao.getDefinition("test.def.toextend", null));
+        assertNotNull("test.def.overridden definition not found.",
+                definitionDao.getDefinition("test.def.overridden", null));
+        assertNotNull("test.def.overridden definition in FRENCH locale not found.",
+                definitionDao.getDefinition("test.def.overridden", Locale.FRENCH));
+
+        assertEquals("Incorrect default country value", "default", definitionDao.getDefinition("test.def1", null)
+                .getAttribute("country").getValue());
+        assertEquals("Incorrect US country value", "US", definitionDao.getDefinition("test.def1", Locale.US)
+                .getAttribute("country").getValue());
+        assertEquals("Incorrect France country value", "France", definitionDao
+                .getDefinition("test.def1", Locale.FRENCH).getAttribute("country").getValue());
+        assertEquals("Incorrect Chinese country value (should be default)", "default",
+                definitionDao.getDefinition("test.def1", Locale.CHINA).getAttribute("country").getValue());
+        assertEquals("Incorrect default country value", "default",
+                definitionDao.getDefinition("test.def.overridden", null).getAttribute("country").getValue());
+        assertEquals("Incorrect default title value", "Definition to be overridden",
+                definitionDao.getDefinition("test.def.overridden", null).getAttribute("title").getValue());
+        assertEquals("Incorrect France country value", "France",
+                definitionDao.getDefinition("test.def.overridden", Locale.FRENCH).getAttribute("country").getValue());
+        assertEquals("Incorrect France title value", "Definition to be extended",
+                definitionDao.getDefinition("test.def.overridden", Locale.FRENCH).getAttribute("title").getValue());
+    }
+
+    /**
+     * Tests {@link LocaleUrlDefinitionDAO#getDefinitions(Locale)}.
+     */
+    @Test
+    public void testGetDefinitions() {
+        List<ApplicationResource> sourceURLs = new ArrayList<ApplicationResource>();
+        sourceURLs.add(url1);
+        sourceURLs.add(url2);
+        sourceURLs.add(url3);
+        definitionDao.setSources(sourceURLs);
+        DefinitionsReader reader = new DigesterDefinitionsReader();
+        definitionDao.setReader(reader);
+
+        Map<String, Definition> defaultDefinitions = definitionDao.getDefinitions(null);
+        Map<String, Definition> usDefinitions = definitionDao.getDefinitions(Locale.US);
+        Map<String, Definition> frenchDefinitions = definitionDao.getDefinitions(Locale.FRENCH);
+        Map<String, Definition> chinaDefinitions = definitionDao.getDefinitions(Locale.CHINA);
+        Map<String, Definition> canadaFrendDefinitions = definitionDao.getDefinitions(Locale.CANADA_FRENCH);
+
+        assertNotNull("test.def1 definition not found.", defaultDefinitions.get("test.def1"));
+        assertNotNull("test.def2 definition not found.", defaultDefinitions.get("test.def2"));
+        assertNotNull("test.def3 definition not found.", defaultDefinitions.get("test.def3"));
+        assertNotNull("test.common definition not found.", defaultDefinitions.get("test.common"));
+        assertNotNull("test.common definition in US locale not found.", usDefinitions.get("test.common"));
+        assertNotNull("test.common definition in FRENCH locale not found.", frenchDefinitions.get("test.common"));
+        assertNotNull("test.common definition in CHINA locale not found.", chinaDefinitions.get("test.common"));
+        assertNotNull("test.common.french definition in FRENCH locale not found.",
+                canadaFrendDefinitions.get("test.common.french"));
+        assertNotNull("test.common.french definition in CANADA_FRENCH locale not found.",
+                canadaFrendDefinitions.get("test.common.french"));
+        assertNotNull("test.def.toextend definition not found.", defaultDefinitions.get("test.def.toextend"));
+        assertNotNull("test.def.overridden definition not found.", defaultDefinitions.get("test.def.overridden"));
+        assertNotNull("test.def.overridden definition in FRENCH locale not found.",
+                frenchDefinitions.get("test.def.overridden"));
+
+        assertEquals("Incorrect default country value", "default",
+                defaultDefinitions.get("test.def1").getAttribute("country").getValue());
+        assertEquals("Incorrect US country value", "US", usDefinitions.get("test.def1").getAttribute("country")
+                .getValue());
+        assertEquals("Incorrect France country value", "France",
+                frenchDefinitions.get("test.def1").getAttribute("country").getValue());
+        assertEquals("Incorrect Chinese country value (should be default)", "default", chinaDefinitions
+                .get("test.def1").getAttribute("country").getValue());
+        assertEquals("Incorrect default country value", "default", defaultDefinitions.get("test.def.overridden")
+                .getAttribute("country").getValue());
+        assertEquals("Incorrect default title value", "Definition to be overridden",
+                defaultDefinitions.get("test.def.overridden").getAttribute("title").getValue());
+        assertEquals("Incorrect France country value", "France", frenchDefinitions.get("test.def.overridden")
+                .getAttribute("country").getValue());
+        assertEquals("Incorrect France title value", "Definition to be extended",
+                frenchDefinitions.get("test.def.overridden").getAttribute("title").getValue());
+    }
+
+    /**
+     * Tests {@link LocaleUrlDefinitionDAO#setSources(List)}.
+     */
+    @Test
+    public void testSetSourceURLs() {
+        List<ApplicationResource> sourceURLs = new ArrayList<ApplicationResource>();
+        sourceURLs.add(url1);
+        sourceURLs.add(url2);
+        sourceURLs.add(url3);
+        definitionDao.setSources(sourceURLs);
+        assertEquals("The source URLs are not set correctly", sourceURLs, definitionDao.sources);
+    }
+
+    /**
+     * Tests {@link LocaleUrlDefinitionDAO#setReader(DefinitionsReader)}.
+     */
+    @Test
+    public void testSetReader() {
+        DefinitionsReader reader = createMock(DefinitionsReader.class);
+        definitionDao.setReader(reader);
+        assertEquals("There reader has not been set correctly", reader, definitionDao.reader);
+    }
+
+    /**
+     * Tests {@link ResolvingLocaleUrlDefinitionDAO#resolveInheritance(Definition, Map, Locale, Set)}.
+     */
+    @Test(expected = NoSuchDefinitionException.class)
+    public void testResolveInheritanceNoParent() {
+        Definition definition = new Definition("mydef", null, null);
+        definition.setExtends("otherDef");
+        definitionDao.resolveInheritance(definition, new HashMap<String, Definition>(), Locale.ITALY,
+                new HashSet<String>());
+    }
+
+    /**
+     * Tests execution.
+     *
+     * @throws IOException If something goes wrong.
+     */
+    @Test
+    public void testInit() throws IOException {
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        Set<ApplicationResource> urlSet = new HashSet<ApplicationResource>();
+        urlSet.add(url1);
+        expect(applicationContext.getResources("/WEB-INF/tiles.xml")).andReturn(urlSet);
+        replay(applicationContext);
+        DefinitionsReader reader = new DigesterDefinitionsReader();
+        definitionDao.setReader(reader);
+        List<ApplicationResource> sourceURLs = new ArrayList<ApplicationResource>();
+        sourceURLs.add(url1);
+        definitionDao.setSources(sourceURLs);
+        assertEquals("The reader is not of the correct class", DigesterDefinitionsReader.class,
+                definitionDao.reader.getClass());
+        assertEquals("The source URLs are not correct", sourceURLs, definitionDao.sources);
+        reset(applicationContext);
+
+        applicationContext = createMock(ApplicationContext.class);
+        replay(applicationContext);
+        definitionDao.setReader(new MockDefinitionsReader());
+        assertEquals("The reader is not of the correct class", MockDefinitionsReader.class,
+                definitionDao.reader.getClass());
+        sourceURLs = new ArrayList<ApplicationResource>();
+        sourceURLs.add(url1);
+        sourceURLs.add(url2);
+        sourceURLs.add(url3);
+        definitionDao.setSources(sourceURLs);
+        assertEquals("The source URLs are not correct", sourceURLs, definitionDao.sources);
+        verify(applicationContext);
+    }
+
+    /**
+     * Tests wildcard mappings.
+     */
+    @Test
+    public void testWildcardMapping() {
+        List<ApplicationResource> urls = new ArrayList<ApplicationResource>();
+        urls.add(urlWildcard);
+        definitionDao.setSources(urls);
+        definitionDao.setReader(new DigesterDefinitionsReader());
+
+        Definition definition = definitionDao.getDefinition("test.defName.subLayered", Locale.ITALY);
+        assertEquals("The template is not correct", "/testName.jsp", definition.getTemplateAttribute().getValue());
+        assertEquals("The header attribute is not correct", "/common/headerLayered.jsp",
+                definition.getAttribute("header").getValue());
+        definition = definitionDao.getDefinition("test.defName.subLayered", Locale.ITALIAN);
+        assertEquals("The template is not correct", "/testName.jsp", definition.getTemplateAttribute().getValue());
+        assertEquals("The header attribute is not correct", "/common/headerLayered.jsp",
+                definition.getAttribute("header").getValue());
+        definition = definitionDao.getDefinition("test.defName.subLayered", null);
+        assertEquals("The template is not correct", "/testName.jsp", definition.getTemplateAttribute().getValue());
+        assertEquals("The header attribute is not correct", "/common/headerLayered.jsp",
+                definition.getAttribute("header").getValue());
+        definition = definitionDao.getDefinition("test.defName.noAttribute", null);
+        assertEquals("/testName.jsp", definition.getTemplateAttribute().getValue());
+        assertEquals(null, definition.getLocalAttributeNames());
+        definition = definitionDao.getDefinition("test.def3", null);
+        assertNotNull("The simple definition is null", definition);
+
+        definition = definitionDao.getDefinition("test.extended.defName.subLayered", null);
+        assertEquals("test.defName.subLayered", definition.getExtends());
+        assertEquals(ATTRIBUTE_NAMES_COUNT, definition.getLocalAttributeNames().size());
+        assertEquals("The template is not correct", "/testName.jsp", definition.getTemplateAttribute().getValue());
+        assertEquals("Overridden Title", definition.getAttribute("title").getValue());
+        assertEquals("The header attribute is not correct", "/common/headerLayered.jsp",
+                definition.getAttribute("header").getValue());
+    }
+
+    /**
+     * Tests
+     * {@link ResolvingLocaleUrlDefinitionDAO#getDefinition(String, Locale)}
+     * when loading multiple files for a locale.
+     */
+    @Test
+    public void testListAttributeLocaleInheritance() {
+        List<ApplicationResource> urls = new ArrayList<ApplicationResource>();
+        urls.add(url21);
+        definitionDao.setSources(urls);
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        definitionDao.setReader(new DigesterDefinitionsReader());
+        replay(applicationContext);
+
+        Definition definition = definitionDao.getDefinition("test.inherit.list", Locale.ITALIAN);
+        ListAttribute listAttribute = (ListAttribute) definition.getAttribute("list");
+        List<Attribute> attributes = listAttribute.getValue();
+        assertEquals(2, attributes.size());
+        verify(applicationContext);
+    }
+
+    /**
+     * Tests
+     * {@link ResolvingLocaleUrlDefinitionDAO#getDefinition(String, Locale)}
+     * to solve the TILES-512 issue.
+     *
+     * @throws IOException If something goes wrong.
+     */
+    public void testTiles512() throws IOException {
+        List<ApplicationResource> urls = new ArrayList<ApplicationResource>();
+        urls.add(url21);
+        definitionDao.setSources(urls);
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        definitionDao.setReader(new DigesterDefinitionsReader());
+        replay(applicationContext);
+
+        Definition definition = definitionDao.getDefinition("test.inherit.othertype", Locale.ITALIAN);
+        assertEquals("/layout.ftl", definition.getTemplateAttribute().getValue());
+        assertEquals("freemarker", definition.getTemplateAttribute().getRenderer());
+    }
+
+    /**
+     * Tests
+     * {@link ResolvingLocaleUrlDefinitionDAO#getDefinition(String, Locale)}
+     * to solve the TILES-513 issue.
+     *
+     * @throws IOException If something goes wrong.
+     */
+    public void testTiles513() throws IOException {
+        List<ApplicationResource> urls = new ArrayList<ApplicationResource>();
+        urls.add(url513);
+        definitionDao.setSources(urls);
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        definitionDao.setReader(new DigesterDefinitionsReader());
+        replay(applicationContext);
+
+        Definition definition = definitionDao.getDefinition("test.anonymous", null);
+        definitionDao.getDefinition("test.anonymous", new Locale("es", "CO"));
+        definitionDao.getDefinition("test.anonymous", new Locale("en", "CA"));
+        Attribute attribute = definition.getAttribute("header");
+        Definition child = definitionDao.getDefinition((String) attribute.getValue(), null);
+        assertNotNull(child);
+        attribute = definition.getAttribute("menu");
+        child = definitionDao.getDefinition((String) attribute.getValue(), null);
+        assertNotNull(child);
+        attribute = definition.getAttribute("footer");
+        child = definitionDao.getDefinition((String) attribute.getValue(), null);
+        assertNotNull(child);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/digester/DigesterDefinitionsReaderExceptionTest.java b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/digester/DigesterDefinitionsReaderExceptionTest.java
new file mode 100644
index 000000000..cd73885e5
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/digester/DigesterDefinitionsReaderExceptionTest.java
@@ -0,0 +1,77 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition.digester;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+/**
+ * Tests {@link DigesterDefinitionsReaderException}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class DigesterDefinitionsReaderExceptionTest {
+
+    /**
+     * Test method for {@link DigesterDefinitionsReaderException#DigesterDefinitionsReaderException()}.
+     */
+    @Test
+    public void testDigesterDefinitionsReaderException() {
+        DigesterDefinitionsReaderException exception = new DigesterDefinitionsReaderException();
+        assertNull(exception.getMessage());
+        assertNull(exception.getCause());
+    }
+
+    /**
+     * Test method for {@link DigesterDefinitionsReaderException#DigesterDefinitionsReaderException(java.lang.String)}.
+     */
+    @Test
+    public void testDigesterDefinitionsReaderExceptionString() {
+        DigesterDefinitionsReaderException exception = new DigesterDefinitionsReaderException("my message");
+        assertEquals("my message", exception.getMessage());
+        assertNull(exception.getCause());
+    }
+
+    /**
+     * Test method for {@link DigesterDefinitionsReaderException#DigesterDefinitionsReaderException(Throwable)}.
+     */
+    @Test
+    public void testDigesterDefinitionsReaderExceptionThrowable() {
+        Throwable cause = new Throwable();
+        DigesterDefinitionsReaderException exception = new DigesterDefinitionsReaderException(cause);
+        assertEquals(cause.toString(), exception.getMessage());
+        assertEquals(cause, exception.getCause());
+    }
+
+    /**
+     * Test method for {@link DigesterDefinitionsReaderException#DigesterDefinitionsReaderException(String, Throwable)}.
+     */
+    @Test
+    public void testDigesterDefinitionsReaderExceptionStringThrowable() {
+        Throwable cause = new Throwable();
+        DigesterDefinitionsReaderException exception = new DigesterDefinitionsReaderException("my message", cause);
+        assertEquals("my message", exception.getMessage());
+        assertEquals(cause, exception.getCause());
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/digester/TestDigesterDefinitionsReader.java b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/digester/TestDigesterDefinitionsReader.java
new file mode 100644
index 000000000..44742feb8
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/digester/TestDigesterDefinitionsReader.java
@@ -0,0 +1,320 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition.digester;
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.Definition;
+import org.apache.tiles.ListAttribute;
+import org.apache.tiles.definition.DefinitionsFactoryException;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Tests the <code>org.apache.tiles.definition.digester.DigesterDefinitionsReader</code> class.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TestDigesterDefinitionsReader {
+
+    /**
+     * The logging object.
+     */
+    private final Logger log = LoggerFactory
+            .getLogger(TestDigesterDefinitionsReader.class);
+
+    /**
+     * The definitions reader.
+     */
+    private DigesterDefinitionsReader reader;
+
+    /**
+     * Sets up the test.
+     *
+     * @throws Exception
+     */
+    @Before
+    public void setUp() {
+        reader = new DigesterDefinitionsReader();
+    }
+
+    /**
+     * Tests the read method under normal conditions.
+     * @throws IOException If something goes wrong.
+     */
+    @Test
+    public void testRead() throws IOException {
+        URL configFile = this.getClass().getClassLoader().getResource(
+                "org/apache/tiles/config/tiles-defs.xml");
+        assertNotNull("Config file not found", configFile);
+
+        InputStream source = configFile.openStream();
+        Map<String, Definition> definitions = reader.read(source);
+
+        assertNotNull("Definitions not returned.", definitions);
+        assertNotNull("Couldn't find doc.mainLayout tile.",
+                definitions.get("doc.mainLayout"));
+        assertNotNull("Couldn't Find title attribute.", definitions.get(
+                "doc.mainLayout").getAttribute("title").getValue());
+        assertEquals("Incorrect Find title attribute.",
+                "Tiles Library Documentation", definitions.get(
+                        "doc.mainLayout").getAttribute("title").getValue());
+
+        Definition def = definitions.get("doc.role.test");
+        assertNotNull("Couldn't find doc.role.test tile.", def);
+        Attribute attribute = def.getAttribute("title");
+        assertNotNull("Couldn't Find title attribute.", attribute
+                .getValue());
+        assertEquals("Role 'myrole' expected", attribute.getRole(),
+                "myrole");
+
+        def = definitions.get("doc.listattribute.test");
+        assertNotNull("Couldn't find doc.listattribute.test tile.", def);
+        attribute = def.getAttribute("items");
+        assertNotNull("Couldn't Find items attribute.", attribute);
+        assertTrue("The class of the attribute is not right",
+                attribute instanceof ListAttribute);
+        assertTrue("The class of value of the attribute is not right",
+                attribute.getValue() instanceof List);
+    }
+
+
+    /**
+     * Tests the read method under normal conditions for the new features in 2.1
+     * version of the DTD.
+     * @throws IOException If something goes wrong.
+     */
+    @Test
+    public void testRead21Version() throws IOException {
+        URL configFile = this.getClass().getClassLoader().getResource(
+                "org/apache/tiles/config/tiles-defs-2.1.xml");
+        assertNotNull("Config file not found", configFile);
+
+        InputStream source = configFile.openStream();
+        Map<String, Definition> definitions = reader.read(source);
+
+        assertNotNull("Definitions not returned.", definitions);
+        Definition def = definitions.get("doc.cascaded.test");
+
+        assertNotNull("Couldn't find doc.role.test tile.", def);
+        Attribute attribute = def.getLocalAttribute("title");
+        assertNotNull("Couldn't Find title local attribute.", attribute);
+        attribute = def.getCascadedAttribute("title2");
+        assertNotNull("Couldn't Find title2 cascaded attribute.", attribute);
+        attribute = def.getLocalAttribute("items1");
+        assertNotNull("Couldn't Find items1 local attribute.", attribute);
+        attribute = def.getCascadedAttribute("items2");
+        assertNotNull("Couldn't Find items2 cascaded attribute.", attribute);
+
+        def = definitions.get("test.nesting.definitions");
+        assertNotNull("Couldn't find test.nesting.definitions tile.", def);
+        assertEquals("/layout.jsp", def.getTemplateAttribute().getValue());
+        assertEquals("template", def.getTemplateAttribute().getRenderer());
+        attribute = def.getAttribute("body");
+        assertNotNull("Couldn't Find body attribute.", attribute);
+        assertEquals("Attribute not of 'definition' type", "definition",
+                attribute.getRenderer());
+        assertNotNull("Attribute value null", attribute.getValue());
+        String defName = attribute.getValue().toString();
+        def = definitions.get(defName);
+        assertNotNull("Couldn't find " + defName + " tile.", def);
+
+        def = definitions.get("test.nesting.list.definitions");
+        assertNotNull("Couldn't find test.nesting.list.definitions tile.",
+                def);
+        attribute = def.getAttribute("list");
+        assertNotNull("Couldn't Find list attribute.", attribute);
+        assertTrue("Attribute not of valid type",
+                attribute instanceof ListAttribute);
+        ListAttribute listAttribute = (ListAttribute) attribute;
+        List<Attribute> list = listAttribute.getValue();
+        assertEquals("The list is not of correct size", 1, list.size());
+        attribute = list.get(0);
+        assertNotNull("Couldn't Find element attribute.", attribute);
+        assertEquals("Attribute not of 'definition' type", "definition",
+                attribute.getRenderer());
+        assertNotNull("Attribute value null", attribute.getValue());
+        defName = attribute.getValue().toString();
+        def = definitions.get(defName);
+        assertNotNull("Couldn't find " + defName + " tile.", def);
+
+        defName = "test.inherit.list.base";
+        def = definitions.get(defName);
+        assertNotNull("Couldn't find " + defName + " tile.", def);
+        defName = "test.inherit.list";
+        def = definitions.get(defName);
+        assertNotNull("Couldn't find " + defName + " tile.", def);
+        listAttribute = (ListAttribute) def.getAttribute("list");
+        assertEquals("This definition does not inherit its list attribute",
+                true, listAttribute.isInherit());
+        defName = "test.noinherit.list";
+        def = definitions.get(defName);
+        listAttribute = (ListAttribute) def.getAttribute("list");
+        assertEquals("This definition inherits its list attribute",
+                false, listAttribute.isInherit());
+
+        defName = "test.new.attributes";
+        def = definitions.get(defName);
+        assertNotNull("Couldn't find " + defName + " tile.", def);
+        Attribute templateAttribute = def.getTemplateAttribute();
+        assertEquals(templateAttribute.getExpressionObject().getExpression(),
+                "${my.expression}");
+        assertEquals("mytype", templateAttribute.getRenderer());
+        attribute = def.getAttribute("body");
+        assertNotNull("Couldn't Find body attribute.", attribute);
+        assertEquals("${my.attribute.expression}", attribute
+                .getExpressionObject().getExpression());
+    }
+
+    /**
+     * Tests read with bad input source.
+     */
+    @Test
+    public void testBadSource() {
+        try {
+            // Read definitions.
+            reader.read(new String("Bad Input"));
+            fail("Should've thrown an exception.");
+        } catch (DefinitionsFactoryException e) {
+            // correct.
+            if (log.isDebugEnabled()) {
+                log.debug("Exception caught, it is OK", e);
+            }
+        } catch (Exception e) {
+            fail("Exception reading configuration." + e);
+        }
+    }
+
+    /**
+     * Tests read with bad XML source.
+     */
+    @Test
+    public void testBadXml() {
+        try {
+            URL configFile = this.getClass().getClassLoader().getResource(
+                    "org/apache/tiles/config/malformed-defs.xml");
+            assertNotNull("Config file not found", configFile);
+
+            InputStream source = configFile.openStream();
+            reader.read(source);
+            fail("Should've thrown an exception.");
+        } catch (DefinitionsFactoryException e) {
+            // correct.
+            if (log.isDebugEnabled()) {
+                log.debug("Exception caught, it is OK", e);
+            }
+        } catch (Exception e) {
+            fail("Exception reading configuration." + e);
+        }
+    }
+
+    /**
+     * Tests the validating input parameter.
+     *
+     * This test case enables Digester's validating property then passes in a
+     * configuration file with invalid XML.
+     */
+    @Test
+    public void testValidatingParameter() {
+        // Testing with default (validation ON).
+        try {
+            URL configFile = this.getClass().getClassLoader().getResource(
+                    "org/apache/tiles/config/invalid-defs.xml");
+            assertNotNull("Config file not found", configFile);
+
+            InputStream source = configFile.openStream();
+            reader.setValidating(true);
+            reader.read(source);
+            fail("Should've thrown an exception.");
+        } catch (DefinitionsFactoryException e) {
+            // correct.
+            if (log.isDebugEnabled()) {
+                log.debug("Exception caught, it is OK", e);
+            }
+        } catch (Exception e) {
+            fail("Exception reading configuration." + e);
+        }
+
+        // Testing with validation OFF.
+        try {
+            setUp();
+            URL configFile = this.getClass().getClassLoader().getResource(
+                    "org/apache/tiles/config/invalid-defs.xml");
+            assertNotNull("Config file not found", configFile);
+
+            InputStream source = configFile.openStream();
+            reader.read(source);
+        } catch (DefinitionsFactoryException e) {
+            fail("Should not have thrown an exception." + e);
+        } catch (Exception e) {
+            fail("Exception reading configuration." + e);
+        }
+    }
+
+    /**
+     * Regression test for bug TILES-352.
+     *
+     * @throws IOException If something goes wrong.
+     */
+    @Test
+    public void testRegressionTiles352() throws IOException {
+        URL configFile = this.getClass().getClassLoader().getResource(
+                "org/apache/tiles/config/defs_regression_TILES-352.xml");
+        assertNotNull("Config file not found", configFile);
+
+        InputStream source = configFile.openStream();
+        Map<String, Definition> name2defs = reader.read(source);
+        source.close();
+        Definition root = name2defs.get("root");
+        Attribute attribute = root.getAttribute("body");
+        Definition child = name2defs.get(attribute.getValue());
+        ListAttribute listAttribute = (ListAttribute) child.getAttribute("list");
+        List<Attribute> list = listAttribute.getValue();
+        assertEquals((list.get(0)).getValue(), "This is a value");
+    }
+
+    /**
+     * Tests {@link DigesterDefinitionsReader#read(Object)}.
+     */
+    @Test
+    public void testReadNoSource() {
+        assertNull(reader.read(null));
+    }
+
+    /**
+     * Tests {@link DigesterDefinitionsReader#addDefinition(Definition)}.
+     */
+    @Test(expected = DigesterDefinitionsReaderException.class)
+    public void testAddDefinitionNoName() {
+        Definition def = new Definition();
+        reader.addDefinition(def);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/pattern/AbstractPatternDefinitionResolverTest.java b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/pattern/AbstractPatternDefinitionResolverTest.java
new file mode 100644
index 000000000..a564e375a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/pattern/AbstractPatternDefinitionResolverTest.java
@@ -0,0 +1,126 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition.pattern;
+
+import static org.junit.Assert.*;
+import static org.easymock.EasyMock.*;
+
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.Definition;
+import org.junit.Test;
+
+/**
+ * Tests {@link AbstractPatternDefinitionResolver}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class AbstractPatternDefinitionResolverTest {
+
+    private DefinitionPatternMatcher firstMatcher;
+    private DefinitionPatternMatcher thirdMatcher;
+
+    private final PatternDefinitionResolver<Integer> resolver = new AbstractPatternDefinitionResolver<Integer>() {
+        @Override
+        protected Map<String, Definition> addDefinitionsAsPatternMatchers(
+                List<DefinitionPatternMatcher> matchers,
+                Map<String, Definition> defsMap) {
+
+            if (defsMap.containsKey("first")) {
+                matchers.add(firstMatcher);
+            }
+            if (defsMap.containsKey("third")) {
+                matchers.add(thirdMatcher);
+            }
+            Map<String, Definition> retValue = new HashMap<String, Definition>(defsMap);
+            retValue.remove("first");
+            retValue.remove("third");
+            return retValue;
+        }
+    };
+
+    /**
+     * Test method for
+     * {@link BasicPatternDefinitionResolver#resolveDefinition(String, Object)}.
+     */
+    @Test
+    public void testResolveDefinition() {
+        testResolveDefinitionImpl();
+    }
+
+    /**
+     * Test method for
+     * {@link BasicPatternDefinitionResolver#clearPatternPaths(Object)}.
+     */
+    @Test
+    public void testClearPatternPaths() {
+        testResolveDefinitionImpl();
+        resolver.clearPatternPaths(1);
+        resolver.clearPatternPaths(2);
+        testResolveDefinitionImpl();
+    }
+
+    private void testResolveDefinitionImpl() {
+
+        firstMatcher = createMock(DefinitionPatternMatcher.class);
+        thirdMatcher = createMock(DefinitionPatternMatcher.class);
+
+        Definition firstDefinition = new Definition("first", (Attribute) null, null);
+        Definition secondDefinition = new Definition("second", (Attribute) null, null);
+        Definition thirdDefinition = new Definition("third", (Attribute) null, null);
+
+        Definition firstTransformedDefinition = new Definition("firstTransformed", (Attribute) null, null);
+        Definition thirdTransformedDefinition = new Definition("thirdTransformed", (Attribute) null, null);
+
+        expect(firstMatcher.createDefinition("firstTransformed")).andReturn(firstTransformedDefinition);
+        expect(firstMatcher.createDefinition("secondTransformed")).andReturn(null);
+        expect(firstMatcher.createDefinition("thirdTransformed")).andReturn(null);
+        expect(thirdMatcher.createDefinition("thirdTransformed")).andReturn(thirdTransformedDefinition).times(2);
+        expect(thirdMatcher.createDefinition("firstTransformed")).andReturn(null);
+        expect(thirdMatcher.createDefinition("secondTransformed")).andReturn(null).times(2);
+
+        replay(firstMatcher, thirdMatcher);
+
+        Map<String, Definition> localeDefsMap = new LinkedHashMap<String, Definition>();
+        localeDefsMap.put("first", firstDefinition);
+        localeDefsMap.put("second", secondDefinition);
+        localeDefsMap.put("third", thirdDefinition);
+        resolver.storeDefinitionPatterns(localeDefsMap, 1);
+        localeDefsMap = new LinkedHashMap<String, Definition>();
+        localeDefsMap.put("third", thirdDefinition);
+        resolver.storeDefinitionPatterns(localeDefsMap, 2);
+        assertEquals(firstTransformedDefinition, resolver.resolveDefinition(
+                "firstTransformed", 1));
+        assertNull(resolver.resolveDefinition("secondTransformed", 1));
+        assertEquals(thirdTransformedDefinition, resolver.resolveDefinition(
+                "thirdTransformed", 1));
+        assertNull(resolver.resolveDefinition("firstTransformed", 2));
+        assertNull(resolver.resolveDefinition("secondTransformed", 2));
+        assertEquals(thirdTransformedDefinition, resolver.resolveDefinition(
+                "thirdTransformed", 2));
+        verify(firstMatcher, thirdMatcher);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/pattern/BasicPatternDefinitionResolverTest.java b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/pattern/BasicPatternDefinitionResolverTest.java
new file mode 100644
index 000000000..31627ec5f
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/pattern/BasicPatternDefinitionResolverTest.java
@@ -0,0 +1,84 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition.pattern;
+
+import static org.junit.Assert.*;
+import static org.easymock.EasyMock.*;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.Definition;
+import org.junit.Test;
+
+/**
+ * Tests {@link BasicPatternDefinitionResolver}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class BasicPatternDefinitionResolverTest {
+
+    /**
+     * Test method for
+     * {@link BasicPatternDefinitionResolver#addDefinitionsAsPatternMatchers(java.util.List, Map)}.
+     */
+    @Test
+    public void testAddDefinitionsAsPatternMatchers() {
+        DefinitionPatternMatcherFactory factory = createMock(DefinitionPatternMatcherFactory.class);
+        PatternRecognizer recognizer = createMock(PatternRecognizer.class);
+        DefinitionPatternMatcher firstMatcher = createMock(DefinitionPatternMatcher.class);
+        DefinitionPatternMatcher thirdMatcher = createMock(DefinitionPatternMatcher.class);
+
+        expect(recognizer.isPatternRecognized("first")).andReturn(true);
+        expect(recognizer.isPatternRecognized("second")).andReturn(false);
+        expect(recognizer.isPatternRecognized("third")).andReturn(true);
+
+        Definition firstDefinition = new Definition("first", (Attribute) null,
+                null);
+        Definition secondDefinition = new Definition("second",
+                (Attribute) null, null);
+        Definition thirdDefinition = new Definition("third", (Attribute) null,
+                null);
+
+        expect(factory.createDefinitionPatternMatcher("first", firstDefinition))
+                .andReturn(firstMatcher);
+        expect(factory.createDefinitionPatternMatcher("third", thirdDefinition))
+                .andReturn(thirdMatcher);
+
+        replay(factory, recognizer, firstMatcher, thirdMatcher);
+        BasicPatternDefinitionResolver<Integer> resolver = new BasicPatternDefinitionResolver<Integer>(
+                factory, recognizer);
+        Map<String, Definition> localeDefsMap = new LinkedHashMap<String, Definition>();
+        localeDefsMap.put("first", firstDefinition);
+        localeDefsMap.put("second", secondDefinition);
+        localeDefsMap.put("third", thirdDefinition);
+        List<DefinitionPatternMatcher> matchers = new ArrayList<DefinitionPatternMatcher>();
+        resolver.addDefinitionsAsPatternMatchers(matchers, localeDefsMap);
+        assertEquals(2, matchers.size());
+        assertEquals(firstMatcher, matchers.get(0));
+        assertEquals(thirdMatcher, matchers.get(1));
+        verify(factory, recognizer, firstMatcher, thirdMatcher);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/pattern/PatternUtilTest.java b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/pattern/PatternUtilTest.java
new file mode 100644
index 000000000..17a5cf07a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/pattern/PatternUtilTest.java
@@ -0,0 +1,322 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition.pattern;
+
+import static org.junit.Assert.*;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.Definition;
+import org.apache.tiles.Expression;
+import org.apache.tiles.ListAttribute;
+import org.junit.Test;
+
+/**
+ * Tests {@link PatternUtil}.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public class PatternUtilTest {
+
+    /**
+     * The size of the list in the main list attribute.
+     */
+    private static final int LIST_ATTRIBUTE_SIZE = 3;
+
+    /**
+     * Test method for
+     * {@link PatternUtil#replacePlaceholders(Definition, String, Object[])}.
+     */
+    @Test
+    public void testReplacePlaceholders() {
+        Map<String, Attribute> attributes = new HashMap<String, Attribute>();
+        attributes.put("attrib1", new Attribute("value{2}"));
+        attributes.put("attrib2", new Attribute("value{2}{3}"));
+        attributes.put("attrib3", new Attribute(null, Expression
+                .createExpression("expr{1}", "EL"), null, null));
+        Definition definition = new Definition("definitionName", new Attribute(
+                "template{1}"), attributes);
+        definition.setExtends("{2}ext");
+        definition.setPreparer("{3}prep");
+        Definition nudef = PatternUtil.replacePlaceholders(definition, "nudef",
+                "value0", "value1", "value2", "value3");
+        assertEquals("nudef", nudef.getName());
+        assertEquals("value2ext", nudef.getExtends());
+        assertEquals("value3prep", nudef.getPreparer());
+        Attribute attribute = nudef.getTemplateAttribute();
+        assertEquals("templatevalue1", attribute.getValue());
+        attribute = nudef.getAttribute("attrib1");
+        assertEquals("valuevalue2", attribute.getValue());
+        attribute = nudef.getAttribute("attrib2");
+        assertEquals("valuevalue2value3", attribute.getValue());
+        attribute = nudef.getAttribute("attrib3");
+        assertEquals("exprvalue1", attribute.getExpressionObject().getExpression());
+    }
+
+    /**
+     * Test method for
+     * {@link PatternUtil#replacePlaceholders(Definition, String, Object[])}.
+     */
+    @Test
+    public void testReplacePlaceholdersNullTemplate() {
+        Map<String, Attribute> attributes = new HashMap<String, Attribute>();
+        attributes.put("attrib1", new Attribute("value{2}"));
+        attributes.put("attrib2", new Attribute("value{2}{3}"));
+        Definition definition = new Definition("definitionName", (Attribute) null, attributes);
+        Definition nudef = PatternUtil.replacePlaceholders(definition, "nudef",
+                "value0", "value1", "value2", "value3");
+        assertEquals("nudef", nudef.getName());
+        assertNull(nudef.getTemplateAttribute());
+        Attribute attribute = nudef.getAttribute("attrib1");
+        assertEquals("valuevalue2", attribute.getValue());
+        attribute = nudef.getAttribute("attrib2");
+        assertEquals("valuevalue2value3", attribute.getValue());
+    }
+
+    /**
+     * Test method for
+     * {@link PatternUtil#replacePlaceholders(Definition, String, Object[])}.
+     */
+    @Test
+    public void testReplacePlaceholdersCascadedAttributes() {
+        Definition definition = new Definition("definitionName", new Attribute(
+                "template{1}"), null);
+        definition.putAttribute("attrib1", new Attribute("value{2}"), true);
+        definition.putAttribute("attrib2", new Attribute("value{2}{3}"), true);
+        Definition nudef = PatternUtil.replacePlaceholders(definition, "nudef",
+                "value0", "value1", "value2", "value3");
+        assertEquals("nudef", nudef.getName());
+        Attribute attribute = nudef.getTemplateAttribute();
+        assertEquals("templatevalue1", attribute.getValue());
+        attribute = nudef.getAttribute("attrib1");
+        assertEquals("valuevalue2", attribute.getValue());
+        attribute = nudef.getAttribute("attrib2");
+        assertEquals("valuevalue2value3", attribute.getValue());
+    }
+
+    /**
+     * Test method for
+     * {@link PatternUtil#replacePlaceholders(Definition, String, Object[])}.
+     */
+    @Test
+    public void testReplacePlaceholdersListAttribute() {
+        Map<String, Attribute> attributes = new HashMap<String, Attribute>();
+        ListAttribute listAttribute = new ListAttribute();
+        ListAttribute internalListAttribute = new ListAttribute();
+        listAttribute.setInherit(true);
+        attributes.put("myList", listAttribute);
+        listAttribute.add(new Attribute("value{2}"));
+        listAttribute.add(new Attribute("value{2}{3}"));
+        listAttribute.add(internalListAttribute);
+        internalListAttribute.add(new Attribute("secondvalue{2}"));
+        internalListAttribute.add(new Attribute("secondvalue{2}{3}"));
+        Definition definition = new Definition("definitionName", new Attribute(
+                "template{1}"), attributes);
+        Definition nudef = PatternUtil.replacePlaceholders(definition, "nudef",
+                "value0", "value1", "value2", "value3");
+        assertEquals("nudef", nudef.getName());
+        Attribute attribute = nudef.getTemplateAttribute();
+        assertEquals("templatevalue1", attribute.getValue());
+        ListAttribute nuListAttribute = (ListAttribute) nudef.getAttribute("myList");
+        assertTrue(nuListAttribute.isInherit());
+        List<Attribute> list = nuListAttribute.getValue();
+        assertEquals(LIST_ATTRIBUTE_SIZE, list.size());
+        attribute = list.get(0);
+        assertEquals("valuevalue2", attribute.getValue());
+        attribute = list.get(1);
+        assertEquals("valuevalue2value3", attribute.getValue());
+        ListAttribute evaluatedListAttribute = (ListAttribute) list.get(2);
+        assertFalse(evaluatedListAttribute.isInherit());
+        list = evaluatedListAttribute.getValue();
+        assertEquals(2, list.size());
+        attribute = list.get(0);
+        assertEquals("secondvaluevalue2", attribute.getValue());
+        attribute = list.get(1);
+        assertEquals("secondvaluevalue2value3", attribute.getValue());
+    }
+
+
+    /**
+     * Tests {@link PatternUtil#createExtractedMap(Map, java.util.Set)}.
+     */
+    @Test
+    public void testCreateExtractedMap() {
+        Map<Integer, String> map = new HashMap<Integer, String>();
+        map.put(0, "value0");
+        map.put(1, "value1");
+        map.put(2, "value2");
+        Set<Integer> set = new HashSet<Integer>();
+        set.add(1);
+        set.add(2);
+        Map<Integer, String> extractedMap = PatternUtil.createExtractedMap(map, set);
+        assertEquals(2, extractedMap.size());
+        assertEquals("value1", extractedMap.get(1));
+        assertEquals("value2", extractedMap.get(2));
+    }
+
+    /**
+     * Test method for
+     * {@link PatternUtil#replacePlaceholders(Definition, String, Object[])}.
+     * See TILES-502
+     */
+    @Test
+    public void testReplacePlaceholdersEL_0() {
+        Map<String, Attribute> attributes = new HashMap<String, Attribute>();
+        Attribute attribute = new Attribute("some-{1}-${requestScope.someVariable}.jsp");
+        attribute.setExpressionObject(new Expression((String)attribute.getValue()));
+        attributes.put("something", attribute);
+        Definition definition = new Definition("definitionName", new Attribute("template"), attributes);
+        Definition nudef = PatternUtil.replacePlaceholders(definition, "nudef", "value0", "value1", "value2", "value3");
+        assertEquals("nudef", nudef.getName());
+
+        assertEquals(
+                "some-value1-${requestScope.someVariable}.jsp",
+                nudef.getAttribute("something").getValue());
+
+        assertEquals(
+                "some-value1-${requestScope.someVariable}.jsp",
+                nudef.getAttribute("something").getExpressionObject().getExpression());
+    }
+
+    /**
+     * Test method for
+     * {@link PatternUtil#replacePlaceholders(Definition, String, Object[])}.
+     * See TILES-574
+     */
+    @Test
+    public void testReplacePlaceholdersEL_1() {
+        Map<String, Attribute> attributes = new HashMap<String, Attribute>();
+        Attribute attribute = new Attribute("some-{1}-${requestScope.someVariable}-other-{2}.jsp");
+        attribute.setExpressionObject(new Expression((String)attribute.getValue()));
+        attributes.put("something", attribute);
+        Definition definition = new Definition("definitionName", new Attribute("template"), attributes);
+        Definition nudef = PatternUtil.replacePlaceholders(definition, "nudef", "value0", "value1", "value2", "value3");
+        assertEquals("nudef", nudef.getName());
+
+        assertEquals(
+                "some-value1-${requestScope.someVariable}-other-value2.jsp",
+                nudef.getAttribute("something").getValue());
+
+        assertEquals(
+                "some-value1-${requestScope.someVariable}-other-value2.jsp",
+                nudef.getAttribute("something").getExpressionObject().getExpression());
+    }
+
+    /**
+     * Test method for
+     * {@link PatternUtil#replacePlaceholders(Definition, String, Object[])}.
+     * See TILES-574
+     */
+    @Test
+    public void testReplacePlaceholdersEL_2() {
+        Map<String, Attribute> attributes = new HashMap<String, Attribute>();
+        Attribute attribute = new Attribute("some-${requestScope.someVariable}-other-{1}-${requestScope.someOtherVariable}.jsp");
+        attribute.setExpressionObject(new Expression((String)attribute.getValue()));
+        attributes.put("something", attribute);
+        Definition definition = new Definition("definitionName", new Attribute("template"), attributes);
+        Definition nudef = PatternUtil.replacePlaceholders(definition, "nudef", "value0", "value1", "value2", "value3");
+        assertEquals("nudef", nudef.getName());
+
+        assertEquals(
+                "some-${requestScope.someVariable}-other-value1-${requestScope.someOtherVariable}.jsp",
+                nudef.getAttribute("something").getValue());
+
+        assertEquals(
+                "some-${requestScope.someVariable}-other-value1-${requestScope.someOtherVariable}.jsp",
+                nudef.getAttribute("something").getExpressionObject().getExpression());
+    }
+
+    /**
+     * Test method for
+     * {@link PatternUtil#replacePlaceholders(Definition, String, Object[])}.
+     */
+    @Test
+    public void testReplacePlaceholdersEL_conditional() {
+        Map<String, Attribute> attributes = new HashMap<String, Attribute>();
+        Attribute attribute = new Attribute("{1}/some-other-{2}-${requestScope.someBoolean ? 'a' : 'b'}.jsp");
+        attribute.setExpressionObject(new Expression((String)attribute.getValue()));
+        attributes.put("something", attribute);
+        Definition definition = new Definition("definitionName", new Attribute("template"), attributes);
+        Definition nudef = PatternUtil.replacePlaceholders(definition, "nudef", "value0", "value1", "value2", "value3");
+        assertEquals("nudef", nudef.getName());
+
+        assertEquals(
+                "value1/some-other-value2-${requestScope.someBoolean ? 'a' : 'b'}.jsp",
+                nudef.getAttribute("something").getValue());
+
+        assertEquals(
+                "value1/some-other-value2-${requestScope.someBoolean ? 'a' : 'b'}.jsp",
+                nudef.getAttribute("something").getExpressionObject().getExpression());
+    }
+
+    /**
+     * Test method for
+     * {@link PatternUtil#replacePlaceholders(Definition, String, Object[])}.
+     */
+    @Test
+    public void testReplacePlaceholdersEL_twice() {
+        Map<String, Attribute> attributes = new HashMap<String, Attribute>();
+        Attribute attribute = new Attribute("some-${requestScope.firstVariable}-${requestScope.secondVariable}.jsp");
+        attribute.setExpressionObject(new Expression((String)attribute.getValue()));
+        attributes.put("something", attribute);
+        Definition definition = new Definition("definitionName", new Attribute("template"), attributes);
+        Definition nudef = PatternUtil.replacePlaceholders(definition, "nudef", "value0", "value1", "value2", "value3");
+        assertEquals("nudef", nudef.getName());
+
+        assertEquals(
+                "some-${requestScope.firstVariable}-${requestScope.secondVariable}.jsp",
+                nudef.getAttribute("something").getValue());
+
+        assertEquals(
+                "some-${requestScope.firstVariable}-${requestScope.secondVariable}.jsp",
+                nudef.getAttribute("something").getExpressionObject().getExpression());
+    }
+
+    /**
+     * Test method for
+     * {@link PatternUtil#replacePlaceholders(Definition, String, Object[])}.
+     */
+    @Test
+    public void testReplacePlaceholdersEL_options() {
+        Map<String, Attribute> attributes = new HashMap<String, Attribute>();
+        Attribute attribute = new Attribute("{1}/{options[my_fallback}}/some-other-{2}-${requestScope.someVariable}.jsp");
+        attribute.setExpressionObject(new Expression((String)attribute.getValue()));
+        attributes.put("something", attribute);
+        Definition definition = new Definition("definitionName", new Attribute("template"), attributes);
+        Definition nudef = PatternUtil.replacePlaceholders(definition, "nudef", "value0", "value1", "value2", "value3");
+        assertEquals("nudef", nudef.getName());
+
+        assertEquals(
+                "value1/{options[my_fallback}}/some-other-value2-${requestScope.someVariable}.jsp",
+                nudef.getAttribute("something").getValue());
+
+        assertEquals(
+                "value1/{options[my_fallback}}/some-other-value2-${requestScope.someVariable}.jsp",
+                nudef.getAttribute("something").getExpressionObject().getExpression());
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/pattern/PrefixedPatternDefinitionResolverTest.java b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/pattern/PrefixedPatternDefinitionResolverTest.java
new file mode 100644
index 000000000..aa5f5251f
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/pattern/PrefixedPatternDefinitionResolverTest.java
@@ -0,0 +1,78 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition.pattern;
+
+import static org.junit.Assert.*;
+import static org.easymock.EasyMock.*;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.Definition;
+import org.junit.Test;
+
+/**
+ * Tests {@link PrefixedPatternDefinitionResolver}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class PrefixedPatternDefinitionResolverTest {
+
+    /**
+     * Test method for {@link PrefixedPatternDefinitionResolver#addDefinitionsAsPatternMatchers(List, Map)}.
+     */
+    @Test
+    public void testAddDefinitionsAsPatternMatchers() {
+        DefinitionPatternMatcherFactory factory1 = createMock(DefinitionPatternMatcherFactory.class);
+        DefinitionPatternMatcherFactory factory2 = createMock(DefinitionPatternMatcherFactory.class);
+        DefinitionPatternMatcher matcher1 = createMock(DefinitionPatternMatcher.class);
+        DefinitionPatternMatcher matcher2 = createMock(DefinitionPatternMatcher.class);
+        Definition definition1 = new Definition("DF1:definition1", (Attribute) null, null);
+        Definition definition2 = new Definition("DF2:definition2", (Attribute) null, null);
+        Definition definition3 = new Definition("noLanguageHere", (Attribute) null, null);
+
+        expect(factory1.createDefinitionPatternMatcher("definition1", definition1)).andReturn(matcher1);
+        expect(factory2.createDefinitionPatternMatcher("definition2", definition2)).andReturn(matcher2);
+
+        replay(factory1, factory2, matcher1, matcher2);
+
+        PrefixedPatternDefinitionResolver<Integer> resolver = new PrefixedPatternDefinitionResolver<Integer>();
+        resolver.registerDefinitionPatternMatcherFactory("DF1", factory1);
+        resolver.registerDefinitionPatternMatcherFactory("DF2", factory2);
+        List<DefinitionPatternMatcher> matchers = new ArrayList<DefinitionPatternMatcher>();
+        Map<String, Definition> definitions = new LinkedHashMap<String, Definition>();
+        definitions.put("DF1:definition1", definition1);
+        definitions.put("DF2:definition2", definition2);
+        definitions.put("noLanguageHere", definition3);
+
+        resolver.addDefinitionsAsPatternMatchers(matchers, definitions);
+
+        assertEquals(2, matchers.size());
+        assertEquals(matcher1, matchers.get(0));
+        assertEquals(matcher2, matchers.get(1));
+
+        verify(factory1, factory2, matcher1, matcher2);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/pattern/regexp/RegexpDefinitionPatternMatcherFactoryTest.java b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/pattern/regexp/RegexpDefinitionPatternMatcherFactoryTest.java
new file mode 100644
index 000000000..bc21eb467
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/pattern/regexp/RegexpDefinitionPatternMatcherFactoryTest.java
@@ -0,0 +1,60 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition.pattern.regexp;
+
+import static org.junit.Assert.*;
+
+import org.apache.tiles.Definition;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests {@link RegexpDefinitionPatternMatcherFactory}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class RegexpDefinitionPatternMatcherFactoryTest {
+
+    /**
+     * The object to test.
+     */
+    private RegexpDefinitionPatternMatcherFactory factory;
+
+    /**
+     * Sets up the object to test.
+     */
+    @Before
+    public void setUp() {
+        factory = new RegexpDefinitionPatternMatcherFactory();
+    }
+
+    /**
+     * Test method for
+     * {@link RegexpDefinitionPatternMatcherFactory#createDefinitionPatternMatcher(String, Definition)}
+     * .
+     */
+    @Test
+    public void testCreateDefinitionPatternMatcher() {
+        assertTrue(factory.createDefinitionPatternMatcher("myPattern",
+                new Definition()) instanceof RegexpDefinitionPatternMatcher);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/pattern/regexp/RegexpDefinitionPatternMatcherTest.java b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/pattern/regexp/RegexpDefinitionPatternMatcherTest.java
new file mode 100644
index 000000000..9bf0c1459
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/pattern/regexp/RegexpDefinitionPatternMatcherTest.java
@@ -0,0 +1,57 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition.pattern.regexp;
+
+import static org.junit.Assert.*;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.Definition;
+import org.apache.tiles.definition.pattern.DefinitionPatternMatcher;
+import org.junit.Test;
+
+/**
+ * Tests {@link RegexpDefinitionPatternMatcher}.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public class RegexpDefinitionPatternMatcherTest {
+
+    /**
+     * Test method for
+     * {@link org.apache.tiles.definition.pattern.RegexpPatternDefinitionResolver
+     * #resolveDefinition(java.lang.String, java.lang.Object)}.
+     */
+    @Test
+    public void testResolveDefinition() {
+        Definition def = new Definition();
+        def.setName("testDef(.*)\\.message(.*)");
+        def.setTemplateAttribute(Attribute.createTemplateAttribute("/test{1}.jsp"));
+        def.putAttribute("body", new Attribute("message{2}"));
+        DefinitionPatternMatcher patternMatcher = new RegexpDefinitionPatternMatcher("testDef(.*)\\.message(.*)", def);
+        Definition result = patternMatcher.createDefinition("testDefOne.messageTwo");
+        assertNotNull(result);
+        assertEquals("testDefOne.messageTwo", result.getName());
+        assertEquals("/testOne.jsp", result.getTemplateAttribute().getValue());
+        assertEquals("messageTwo", result.getAttribute("body").getValue());
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/pattern/wildcard/WildcardDefinitionPatternMatcherFactoryTest.java b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/pattern/wildcard/WildcardDefinitionPatternMatcherFactoryTest.java
new file mode 100644
index 000000000..a8508f079
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/pattern/wildcard/WildcardDefinitionPatternMatcherFactoryTest.java
@@ -0,0 +1,70 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition.pattern.wildcard;
+
+import static org.junit.Assert.*;
+
+import org.apache.tiles.Definition;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests {@link WildcardDefinitionPatternMatcherFactory}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class WildcardDefinitionPatternMatcherFactoryTest {
+
+    /**
+     * The object to test.
+     */
+    private WildcardDefinitionPatternMatcherFactory factory;
+
+    /**
+     * Sets up the object to test.
+     */
+    @Before
+    public void setUp() {
+        factory = new WildcardDefinitionPatternMatcherFactory();
+    }
+
+    /**
+     * Test method for
+     * {@link WildcardDefinitionPatternMatcherFactory#createDefinitionPatternMatcher(String, Definition)}
+     * .
+     */
+    @Test
+    public void testCreateDefinitionPatternMatcher() {
+        assertTrue(factory.createDefinitionPatternMatcher("myPattern",
+                new Definition()) instanceof WildcardDefinitionPatternMatcher);
+    }
+
+    /**
+     * Test method for {@link WildcardDefinitionPatternMatcherFactory#isPatternRecognized(String)}.
+     */
+    @Test
+    public void testIsPatternRecognized() {
+        assertTrue(factory.isPatternRecognized("my*pattern"));
+        assertFalse(factory.isPatternRecognized("mypattern"));
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/pattern/wildcard/WildcardDefinitionPatternMatcherTest.java b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/pattern/wildcard/WildcardDefinitionPatternMatcherTest.java
new file mode 100644
index 000000000..380f2ef2f
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/definition/pattern/wildcard/WildcardDefinitionPatternMatcherTest.java
@@ -0,0 +1,57 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition.pattern.wildcard;
+
+import static org.junit.Assert.*;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.Definition;
+import org.apache.tiles.definition.pattern.DefinitionPatternMatcher;
+import org.apache.tiles.util.WildcardHelper;
+import org.junit.Test;
+
+/**
+ * Tests {@link WildcardDefinitionPatternMatcher}.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public class WildcardDefinitionPatternMatcherTest {
+
+    /**
+     * Test method for {@link WildcardDefinitionPatternMatcher#createDefinition(String)}.
+     */
+    @Test
+    public void testResolveDefinition() {
+        Definition def = new Definition();
+        def.setName("testDef*.message*");
+        def.setTemplateAttribute(Attribute.createTemplateAttribute("/test{1}.jsp"));
+        def.putAttribute("body", new Attribute("message{2}"));
+        DefinitionPatternMatcher patternMatcher = new WildcardDefinitionPatternMatcher(
+                "testDef*.message*", def, new WildcardHelper());
+        Definition result = patternMatcher.createDefinition("testDefOne.messageTwo");
+        assertNotNull(result);
+        assertEquals("testDefOne.messageTwo", result.getName());
+        assertEquals("/testOne.jsp", result.getTemplateAttribute().getValue());
+        assertEquals("messageTwo", result.getAttribute("body").getValue());
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/evaluator/BasicAttributeEvaluatorFactoryTest.java b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/evaluator/BasicAttributeEvaluatorFactoryTest.java
new file mode 100644
index 000000000..4733fd3c3
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/evaluator/BasicAttributeEvaluatorFactoryTest.java
@@ -0,0 +1,88 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.evaluator;
+
+import static org.junit.Assert.*;
+import static org.easymock.EasyMock.*;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.Expression;
+import org.junit.Test;
+
+/**
+ * Tests {@link BasicAttributeEvaluatorFactory}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class BasicAttributeEvaluatorFactoryTest {
+
+    /**
+     * Test method for {@link BasicAttributeEvaluatorFactory#getAttributeEvaluator(String)}.
+     */
+    @Test
+    public void testGetAttributeEvaluatorString() {
+        AttributeEvaluator defaultEvaluator = createMock(AttributeEvaluator.class);
+        AttributeEvaluator evaluator1 = createMock(AttributeEvaluator.class);
+        AttributeEvaluator evaluator2 = createMock(AttributeEvaluator.class);
+        replay(defaultEvaluator, evaluator1, evaluator2);
+        BasicAttributeEvaluatorFactory factory = new BasicAttributeEvaluatorFactory(defaultEvaluator);
+        factory.registerAttributeEvaluator("LANG1", evaluator1);
+        factory.registerAttributeEvaluator("LANG2", evaluator2);
+        assertSame(evaluator1, factory.getAttributeEvaluator("LANG1"));
+        assertSame(evaluator2, factory.getAttributeEvaluator("LANG2"));
+        assertSame(defaultEvaluator, factory.getAttributeEvaluator("LANG3"));
+        verify(defaultEvaluator, evaluator1, evaluator2);
+    }
+
+    /**
+     * Test method for {@link BasicAttributeEvaluatorFactory#getAttributeEvaluator(Attribute)}.
+     */
+    @Test
+    public void testGetAttributeEvaluatorAttribute() {
+        AttributeEvaluator defaultEvaluator = createMock(AttributeEvaluator.class);
+        AttributeEvaluator evaluator1 = createMock(AttributeEvaluator.class);
+        AttributeEvaluator evaluator2 = createMock(AttributeEvaluator.class);
+        replay(defaultEvaluator, evaluator1, evaluator2);
+        BasicAttributeEvaluatorFactory factory = new BasicAttributeEvaluatorFactory(defaultEvaluator);
+        factory.registerAttributeEvaluator("LANG1", evaluator1);
+        factory.registerAttributeEvaluator("LANG2", evaluator2);
+        assertSame(evaluator1, factory
+                .getAttributeEvaluator(createExpressionAttribute("LANG1")));
+        assertSame(evaluator2, factory
+                .getAttributeEvaluator(createExpressionAttribute("LANG2")));
+        assertSame(defaultEvaluator, factory
+                .getAttributeEvaluator(createExpressionAttribute("LANG3")));
+        verify(defaultEvaluator, evaluator1, evaluator2);
+    }
+
+    /**
+     * Creates a sample attribute with an expression.
+     *
+     * @param language The expression language.
+     * @return The attribute.
+     */
+    private Attribute createExpressionAttribute(String language) {
+        return new Attribute(null, Expression.createExpression(
+                "myExpression", language), null, "string");
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/evaluator/EvaluatorExceptionTest.java b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/evaluator/EvaluatorExceptionTest.java
new file mode 100644
index 000000000..96cf39104
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/evaluator/EvaluatorExceptionTest.java
@@ -0,0 +1,77 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.evaluator;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+/**
+ * Tests {@link EvaluationException}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class EvaluatorExceptionTest {
+
+    /**
+     * Test method for {@link EvaluationException#EvaluationException()}.
+     */
+    @Test
+    public void testEvaluationException() {
+        EvaluationException exception = new EvaluationException();
+        assertNull(exception.getMessage());
+        assertNull(exception.getCause());
+    }
+
+    /**
+     * Test method for {@link EvaluationException#EvaluationException(java.lang.String)}.
+     */
+    @Test
+    public void testEvaluationExceptionString() {
+        EvaluationException exception = new EvaluationException("my message");
+        assertEquals("my message", exception.getMessage());
+        assertNull(exception.getCause());
+    }
+
+    /**
+     * Test method for {@link EvaluationException#EvaluationException(java.lang.Throwable)}.
+     */
+    @Test
+    public void testEvaluationExceptionThrowable() {
+        Throwable cause = new Throwable();
+        EvaluationException exception = new EvaluationException(cause);
+        assertEquals(cause.toString(), exception.getMessage());
+        assertEquals(cause, exception.getCause());
+    }
+
+    /**
+     * Test method for {@link EvaluationException#EvaluationException(java.lang.String, java.lang.Throwable)}.
+     */
+    @Test
+    public void testEvaluationExceptionStringThrowable() {
+        Throwable cause = new Throwable();
+        EvaluationException exception = new EvaluationException("my message", cause);
+        assertEquals("my message", exception.getMessage());
+        assertEquals(cause, exception.getCause());
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/evaluator/impl/DirectAttributeEvaluatorTest.java b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/evaluator/impl/DirectAttributeEvaluatorTest.java
new file mode 100644
index 000000000..4b4e830be
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/evaluator/impl/DirectAttributeEvaluatorTest.java
@@ -0,0 +1,93 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.evaluator.impl;
+
+import static org.junit.Assert.*;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.Expression;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests {@link DirectAttributeEvaluator}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class DirectAttributeEvaluatorTest {
+
+    /**
+     * The evaluator to test.
+     */
+    private DirectAttributeEvaluator evaluator;
+
+    /**
+     * Sets up the test.
+     */
+    @Before
+    public void setUp() {
+        evaluator = new DirectAttributeEvaluator();
+    }
+
+    /**
+     * Tests
+     * {@link DirectAttributeEvaluator#evaluate(Attribute, org.apache.tiles.request.Request)}.
+     */
+    @Test
+    public void testEvaluate() {
+        String expression = "This is an expression";
+        Attribute attribute = new Attribute(null, Expression.createExpression(
+                expression, null), null, (String) null);
+        Object result = evaluator.evaluate(attribute, null);
+        assertEquals("The expression has not been evaluated correctly", result,
+                expression);
+        expression = "${attributeName}";
+        attribute.setExpressionObject(new Expression(expression));
+        result = evaluator.evaluate(attribute, null);
+        assertEquals("The expression has not been evaluated correctly", result,
+                expression);
+    }
+
+    /**
+     * Tests
+     * {@link DirectAttributeEvaluator#evaluate(Attribute, org.apache.tiles.request.Request)}.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testEvaluateNullAttribute() {
+        evaluator.evaluate((Attribute) null, null);
+    }
+
+    /**
+     * Tests
+     * {@link DirectAttributeEvaluator#evaluate(String, org.apache.tiles.request.Request)}.
+     */
+    @Test
+    public void testEvaluateString() {
+        String expression = "This is an expression";
+        Object result = evaluator.evaluate(expression, null);
+        assertEquals("The expression has not been evaluated correctly", result,
+                expression);
+        expression = "${attributeName}";
+        result = evaluator.evaluate(expression, null);
+        assertEquals("The expression has not been evaluated correctly", result,
+                expression);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/factory/BasicTilesContainerFactoryTest.java b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/factory/BasicTilesContainerFactoryTest.java
new file mode 100644
index 000000000..9e4cac4bb
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/factory/BasicTilesContainerFactoryTest.java
@@ -0,0 +1,253 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.factory;
+
+import static org.easymock.EasyMock.*;
+import static org.easymock.classextension.EasyMock.*;
+
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.definition.DefinitionsFactory;
+import org.apache.tiles.definition.DefinitionsReader;
+import org.apache.tiles.definition.UnresolvingLocaleDefinitionsFactory;
+import org.apache.tiles.definition.digester.DigesterDefinitionsReader;
+import org.apache.tiles.evaluator.AttributeEvaluatorFactory;
+import org.apache.tiles.evaluator.impl.DirectAttributeEvaluator;
+import org.apache.tiles.impl.BasicTilesContainer;
+import org.apache.tiles.locale.LocaleResolver;
+import org.apache.tiles.locale.impl.DefaultLocaleResolver;
+import org.apache.tiles.preparer.factory.BasicPreparerFactory;
+import org.apache.tiles.preparer.factory.PreparerFactory;
+import org.apache.tiles.renderer.DefinitionRenderer;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.ApplicationResource;
+import org.apache.tiles.request.locale.URLApplicationResource;
+import org.apache.tiles.request.render.BasicRendererFactory;
+import org.apache.tiles.request.render.ChainedDelegateRenderer;
+import org.apache.tiles.request.render.DispatchRenderer;
+import org.apache.tiles.request.render.Renderer;
+import org.apache.tiles.request.render.RendererFactory;
+import org.apache.tiles.request.render.StringRenderer;
+import org.easymock.EasyMock;
+
+/**
+ * Tests {@link BasicTilesContainerFactory}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class BasicTilesContainerFactoryTest extends TestCase {
+
+    /**
+     * The factory to test.
+     */
+    private BasicTilesContainerFactory factory;
+
+    /**
+     * The context object.
+     */
+    private ApplicationContext applicationContext;
+
+    /**
+     * The resource to load.
+     */
+    private ApplicationResource resource;
+
+    /** {@inheritDoc} */
+    @Override
+    protected void setUp() throws Exception {
+        applicationContext = EasyMock.createMock(ApplicationContext.class);
+        resource = new URLApplicationResource("/org/apache/tiles/config/tiles-defs.xml", getClass().getResource(
+                "/org/apache/tiles/config/tiles-defs.xml"));
+        EasyMock.expect(applicationContext.getResource("/WEB-INF/tiles.xml")).andReturn(resource);
+        EasyMock.replay(applicationContext);
+        factory = new BasicTilesContainerFactory();
+    }
+
+    /**
+     * Tests {@link BasicTilesContainerFactory#createContainer(ApplicationContext)}.
+     */
+    public void testCreateContainer() {
+        TilesContainer container = factory.createContainer(applicationContext);
+        assertTrue("The class of the container is not correct", container instanceof BasicTilesContainer);
+    }
+
+    /**
+     * Tests {@link BasicTilesContainerFactory#createDefinitionsFactory(
+     * ApplicationContext, LocaleResolver)}.
+     */
+    public void testCreateDefinitionsFactory() {
+        LocaleResolver resolver = factory.createLocaleResolver(applicationContext);
+        DefinitionsFactory defsFactory = factory.createDefinitionsFactory(applicationContext, resolver);
+        assertTrue("The class of the definitions factory is not correct",
+                defsFactory instanceof UnresolvingLocaleDefinitionsFactory);
+    }
+
+    /**
+     * Tests {@link BasicTilesContainerFactory#createLocaleResolver(
+     * ApplicationContext)}.
+     */
+    public void testCreateLocaleResolver() {
+        LocaleResolver localeResolver = factory.createLocaleResolver(applicationContext);
+        assertTrue("The class of the locale resolver is not correct", localeResolver instanceof DefaultLocaleResolver);
+    }
+
+    /**
+     * Tests {@link BasicTilesContainerFactory#createDefinitionsReader(
+     * ApplicationContext)}.
+     */
+    public void testCreateDefinitionsReader() {
+        DefinitionsReader reader = factory.createDefinitionsReader(applicationContext);
+        assertTrue("The class of the reader is not correct", reader instanceof DigesterDefinitionsReader);
+    }
+
+    /**
+     * Tests
+     * {@link BasicTilesContainerFactory#getSources(ApplicationContext)}.
+     */
+    public void testGetSources() {
+        List<ApplicationResource> resources = factory.getSources(applicationContext);
+        assertEquals("The urls list is not one-sized", 1, resources.size());
+        assertEquals("The URL is not correct", resource, resources.get(0));
+    }
+
+    /**
+     * Tests
+     * {@link BasicTilesContainerFactory#createAttributeEvaluatorFactory(
+     * ApplicationContext, LocaleResolver)}.
+     */
+    public void testCreateAttributeEvaluatorFactory() {
+        LocaleResolver resolver = factory.createLocaleResolver(applicationContext);
+        AttributeEvaluatorFactory attributeEvaluatorFactory = factory.createAttributeEvaluatorFactory(
+                applicationContext, resolver);
+        assertTrue("The class of the evaluator is not correct",
+                attributeEvaluatorFactory.getAttributeEvaluator((String) null) instanceof DirectAttributeEvaluator);
+    }
+
+    /**
+     * Tests
+     * {@link BasicTilesContainerFactory#createPreparerFactory(ApplicationContext)}.
+     */
+    public void testCreatePreparerFactory() {
+        PreparerFactory preparerFactory = factory.createPreparerFactory(applicationContext);
+        assertTrue("The class of the preparer factory is not correct", preparerFactory instanceof BasicPreparerFactory);
+    }
+
+    /**
+     * Tests {@link BasicTilesContainerFactory#createRendererFactory(
+     * ApplicationContext, TilesContainer, AttributeEvaluatorFactory)}.
+     */
+    public void testCreateRendererFactory() {
+        TilesContainer container = factory.createContainer(applicationContext);
+        LocaleResolver resolver = factory.createLocaleResolver(applicationContext);
+        AttributeEvaluatorFactory attributeEvaluatorFactory = factory.createAttributeEvaluatorFactory(
+                applicationContext, resolver);
+        RendererFactory rendererFactory = factory.createRendererFactory(applicationContext, container,
+                attributeEvaluatorFactory);
+        assertTrue("The class of the renderer factory is not correct", rendererFactory instanceof BasicRendererFactory);
+        Renderer renderer = rendererFactory.getRenderer("string");
+        assertNotNull("The string renderer is null", renderer);
+        assertTrue("The string renderer class is not correct", renderer instanceof StringRenderer);
+        renderer = rendererFactory.getRenderer("template");
+        assertNotNull("The template renderer is null", renderer);
+        assertTrue("The template renderer class is not correct", renderer instanceof DispatchRenderer);
+        renderer = rendererFactory.getRenderer("definition");
+        assertNotNull("The definition renderer is null", renderer);
+        assertTrue("The definition renderer class is not correct", renderer instanceof DefinitionRenderer);
+    }
+
+    /**
+     * Tests
+     * {@link BasicTilesContainerFactory#createDefaultAttributeRenderer(BasicRendererFactory,
+     * ApplicationContext, TilesContainer, AttributeEvaluatorFactory)}.
+     */
+    public void testCreateDefaultAttributeRenderer() {
+        TilesContainer container = createMock(TilesContainer.class);
+        AttributeEvaluatorFactory attributeEvaluatorFactory = createMock(AttributeEvaluatorFactory.class);
+        BasicRendererFactory rendererFactory = createMock(BasicRendererFactory.class);
+        Renderer stringRenderer = createMock(Renderer.class);
+        Renderer templateRenderer = createMock(Renderer.class);
+        Renderer definitionRenderer = createMock(Renderer.class);
+
+        expect(rendererFactory.getRenderer("string")).andReturn(stringRenderer);
+        expect(rendererFactory.getRenderer("template")).andReturn(templateRenderer);
+        expect(rendererFactory.getRenderer("definition")).andReturn(definitionRenderer);
+
+        replay(container, attributeEvaluatorFactory, rendererFactory);
+        Renderer renderer = factory.createDefaultAttributeRenderer(rendererFactory, applicationContext, container,
+                attributeEvaluatorFactory);
+        assertTrue("The default renderer class is not correct", renderer instanceof ChainedDelegateRenderer);
+        verify(container, attributeEvaluatorFactory, rendererFactory);
+    }
+
+    /**
+     * Tests
+     * {@link BasicTilesContainerFactory#createStringAttributeRenderer(BasicRendererFactory,
+     * ApplicationContext, TilesContainer, AttributeEvaluatorFactory)}.
+     */
+    public void testCreateStringAttributeRenderer() {
+        TilesContainer container = createMock(TilesContainer.class);
+        AttributeEvaluatorFactory attributeEvaluatorFactory = createMock(AttributeEvaluatorFactory.class);
+        BasicRendererFactory rendererFactory = createMock(BasicRendererFactory.class);
+
+        replay(container, attributeEvaluatorFactory, rendererFactory);
+        Renderer renderer = factory.createStringAttributeRenderer(rendererFactory, applicationContext, container,
+                attributeEvaluatorFactory);
+        assertTrue("The renderer class is not correct", renderer instanceof StringRenderer);
+        verify(container, attributeEvaluatorFactory, rendererFactory);
+    }
+
+    /**
+     * Tests
+     * {@link BasicTilesContainerFactory#createTemplateAttributeRenderer(BasicRendererFactory,
+     * ApplicationContext, TilesContainer, AttributeEvaluatorFactory)}.
+     */
+    public void testCreateTemplateAttributeRenderer() {
+        TilesContainer container = createMock(TilesContainer.class);
+        AttributeEvaluatorFactory attributeEvaluatorFactory = createMock(AttributeEvaluatorFactory.class);
+        BasicRendererFactory rendererFactory = createMock(BasicRendererFactory.class);
+
+        replay(container, attributeEvaluatorFactory, rendererFactory);
+        Renderer renderer = factory.createTemplateAttributeRenderer(rendererFactory, applicationContext, container,
+                attributeEvaluatorFactory);
+        assertTrue("The renderer class is not correct", renderer instanceof DispatchRenderer);
+        verify(container, attributeEvaluatorFactory, rendererFactory);
+    }
+
+    /**
+     * Tests
+     * {@link BasicTilesContainerFactory#createDefinitionAttributeRenderer(BasicRendererFactory,
+     * ApplicationContext, TilesContainer, AttributeEvaluatorFactory)}.
+     */
+    public void testCreateDefinitionAttributeRenderer() {
+        TilesContainer container = createMock(TilesContainer.class);
+        AttributeEvaluatorFactory attributeEvaluatorFactory = createMock(AttributeEvaluatorFactory.class);
+        BasicRendererFactory rendererFactory = createMock(BasicRendererFactory.class);
+
+        replay(container, attributeEvaluatorFactory, rendererFactory);
+        Renderer renderer = factory.createDefinitionAttributeRenderer(rendererFactory, applicationContext, container,
+                attributeEvaluatorFactory);
+        assertTrue("The renderer class is not correct", renderer instanceof DefinitionRenderer);
+        verify(container, attributeEvaluatorFactory, rendererFactory);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/factory/TilesContainerFactoryExceptionTest.java b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/factory/TilesContainerFactoryExceptionTest.java
new file mode 100644
index 000000000..751ffea10
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/factory/TilesContainerFactoryExceptionTest.java
@@ -0,0 +1,77 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.factory;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+/**
+ * Tests {@link TilesContainerFactoryException}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TilesContainerFactoryExceptionTest {
+
+    /**
+     * Test method for {@link TilesContainerFactoryException#TilesContainerFactoryException()}.
+     */
+    @Test
+    public void testTilesContainerFactoryException() {
+        TilesContainerFactoryException exception = new TilesContainerFactoryException();
+        assertNull(exception.getMessage());
+        assertNull(exception.getCause());
+    }
+
+    /**
+     * Test method for {@link TilesContainerFactoryException#TilesContainerFactoryException(java.lang.String)}.
+     */
+    @Test
+    public void testTilesContainerFactoryExceptionString() {
+        TilesContainerFactoryException exception = new TilesContainerFactoryException("my message");
+        assertEquals("my message", exception.getMessage());
+        assertNull(exception.getCause());
+    }
+
+    /**
+     * Test method for {@link TilesContainerFactoryException#TilesContainerFactoryException(java.lang.Throwable)}.
+     */
+    @Test
+    public void testTilesContainerFactoryExceptionThrowable() {
+        Throwable cause = new Throwable();
+        TilesContainerFactoryException exception = new TilesContainerFactoryException(cause);
+        assertEquals(cause.toString(), exception.getMessage());
+        assertEquals(cause, exception.getCause());
+    }
+
+    /**
+     * Test method for {@link TilesContainerFactoryException#TilesContainerFactoryException(String, Throwable)}.
+     */
+    @Test
+    public void testTilesContainerFactoryExceptionStringThrowable() {
+        Throwable cause = new Throwable();
+        TilesContainerFactoryException exception = new TilesContainerFactoryException("my message", cause);
+        assertEquals("my message", exception.getMessage());
+        assertEquals(cause, exception.getCause());
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/impl/BasicTilesContainerTest.java b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/impl/BasicTilesContainerTest.java
new file mode 100644
index 000000000..8c9f476d5
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/impl/BasicTilesContainerTest.java
@@ -0,0 +1,149 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.impl;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.net.URL;
+
+import junit.framework.TestCase;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.factory.AbstractTilesContainerFactory;
+import org.apache.tiles.factory.BasicTilesContainerFactory;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.Request;
+import org.apache.tiles.request.locale.URLApplicationResource;
+import org.apache.tiles.request.render.CannotRenderException;
+import org.easymock.EasyMock;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class BasicTilesContainerTest extends TestCase {
+
+    /**
+     * The logging object.
+     */
+    private final Logger log = LoggerFactory
+            .getLogger(BasicTilesContainerTest.class);
+
+    /**
+     * A sample integer value to check object rendering.
+     */
+    private static final int SAMPLE_INT = 15;
+
+    /**
+     * The container.
+     */
+    private BasicTilesContainer container;
+
+    /** {@inheritDoc} */
+    @Override
+    public void setUp() {
+        ApplicationContext context = EasyMock
+                .createMock(ApplicationContext.class);
+        URL url = getClass().getResource("/org/apache/tiles/factory/test-defs.xml");
+        URLApplicationResource resource = new URLApplicationResource("/WEB-INF/tiles.xml", url);
+
+        EasyMock.expect(context.getResource("/WEB-INF/tiles.xml"))
+                .andReturn(resource);
+        EasyMock.replay(context);
+        AbstractTilesContainerFactory factory = new BasicTilesContainerFactory();
+        container = (BasicTilesContainer) factory.createContainer(context);
+    }
+
+    /**
+     * Tests basic Tiles container initialization.
+     */
+    public void testInitialization() {
+        assertNotNull(container);
+        assertNotNull(container.getPreparerFactory());
+        assertNotNull(container.getDefinitionsFactory());
+    }
+
+    /**
+     * Tests that attributes of type "object" won't be rendered.
+     *
+     * @throws IOException If something goes wrong, but it's not a Tiles
+     * exception.
+     */
+    public void testObjectAttribute() throws IOException {
+        Attribute attribute = new Attribute();
+        Request request = EasyMock.createMock(Request.class);
+        EasyMock.replay(request);
+        boolean exceptionFound = false;
+
+        attribute.setValue(new Integer(SAMPLE_INT)); // A simple object
+        try {
+            container.render(attribute, request);
+        } catch (CannotRenderException e) {
+            log.debug("Intercepted a TilesException, it is correct", e);
+            exceptionFound = true;
+        }
+
+        assertTrue("An attribute of 'object' type cannot be rendered",
+                exceptionFound);
+    }
+
+    /**
+     * Tests is attributes are rendered correctly according to users roles.
+     *
+     * @throws IOException If a problem arises during rendering or writing in the writer.
+     */
+    public void testAttributeCredentials() throws IOException {
+        Request request = EasyMock.createMock(Request.class);
+        EasyMock.expect(request.isUserInRole("myrole")).andReturn(Boolean.TRUE);
+        StringWriter writer = new StringWriter();
+        EasyMock.expect(request.getWriter()).andReturn(writer);
+        EasyMock.replay(request);
+        Attribute attribute = new Attribute("This is the value", "myrole");
+        attribute.setRenderer("string");
+        container.render(attribute, request);
+        writer.close();
+        assertEquals("The attribute should have been rendered",
+                "This is the value", writer.toString());
+        EasyMock.reset(request);
+        request = EasyMock.createMock(Request.class);
+        EasyMock.expect(request.isUserInRole("myrole")).andReturn(Boolean.FALSE);
+        EasyMock.replay(request);
+        writer = new StringWriter();
+        container.render(attribute, request);
+        writer.close();
+        assertNotSame("The attribute should have not been rendered",
+                "This is the value", writer);
+    }
+
+    /**
+     * Tests {@link BasicTilesContainer#evaluate(Attribute, Request)}.
+     */
+    public void testEvaluate() {
+        Request request = EasyMock.createMock(Request.class);
+        EasyMock.replay(request);
+        Attribute attribute = new Attribute("This is the value");
+        Object value = container.evaluate(attribute, request);
+        assertEquals("The attribute has not been evaluated correctly",
+                "This is the value", value);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/impl/BasicTilesContainerUnitTest.java b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/impl/BasicTilesContainerUnitTest.java
new file mode 100644
index 000000000..941aeab4a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/impl/BasicTilesContainerUnitTest.java
@@ -0,0 +1,922 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.impl;
+
+import static org.easymock.EasyMock.*;
+import static org.easymock.classextension.EasyMock.*;
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.util.Deque;
+import java.util.LinkedList;
+import java.util.Map;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.AttributeContext;
+import org.apache.tiles.BasicAttributeContext;
+import org.apache.tiles.Definition;
+import org.apache.tiles.definition.DefinitionsFactory;
+import org.apache.tiles.definition.NoSuchDefinitionException;
+import org.apache.tiles.evaluator.AttributeEvaluator;
+import org.apache.tiles.evaluator.AttributeEvaluatorFactory;
+import org.apache.tiles.preparer.ViewPreparer;
+import org.apache.tiles.preparer.factory.NoSuchPreparerException;
+import org.apache.tiles.preparer.factory.PreparerFactory;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.Request;
+import org.apache.tiles.request.render.CannotRenderException;
+import org.apache.tiles.request.render.NoSuchRendererException;
+import org.apache.tiles.request.render.Renderer;
+import org.apache.tiles.request.render.RendererFactory;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests {@link BasicTilesContainer}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class BasicTilesContainerUnitTest {
+
+    /**
+     * Name used to store attribute context stack.
+     */
+    private static final String ATTRIBUTE_CONTEXT_STACK =
+        "org.apache.tiles.AttributeContext.STACK";
+
+    /**
+     * The application context.
+     */
+    private ApplicationContext applicationContext;
+
+    /**
+     * The definitions factory.
+     */
+    private DefinitionsFactory definitionsFactory;
+
+    /**
+     * The preparer factory.
+     */
+    private PreparerFactory preparerFactory;
+
+    /**
+     * The renderer factory.
+     */
+    private RendererFactory rendererFactory;
+
+    /**
+     * The evaluator factory.
+     */
+    private AttributeEvaluatorFactory attributeEvaluatorFactory;
+
+    /**
+     * The container to test.
+     */
+    private BasicTilesContainer container;
+
+    /**
+     * Sets up the test.
+     */
+    @Before
+    public void setUp() {
+        applicationContext = createMock(ApplicationContext.class);
+        definitionsFactory = createMock(DefinitionsFactory.class);
+        preparerFactory = createMock(PreparerFactory.class);
+        rendererFactory = createMock(RendererFactory.class);
+        attributeEvaluatorFactory = createMock(AttributeEvaluatorFactory.class);
+        container = new BasicTilesContainer();
+        container.setApplicationContext(applicationContext);
+        container.setAttributeEvaluatorFactory(attributeEvaluatorFactory);
+        container.setDefinitionsFactory(definitionsFactory);
+        container.setPreparerFactory(preparerFactory);
+        container.setRendererFactory(rendererFactory);
+    }
+
+    /**
+     * Test method for {@link BasicTilesContainer#startContext(Request)}.
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testStartContext() {
+        Request request = createMock(Request.class);
+        Map<String, Object> requestScope = createMock(Map.class);
+        Deque<AttributeContext> deque = createMock(Deque.class);
+        AttributeContext attributeContext = createMock(AttributeContext.class);
+
+        expect(request.getContext("request")).andReturn(requestScope);
+        expect(requestScope.get(ATTRIBUTE_CONTEXT_STACK)).andReturn(deque);
+        expect(deque.isEmpty()).andReturn(false);
+        expect(deque.peek()).andReturn(attributeContext);
+        expect(attributeContext.getCascadedAttributeNames()).andReturn(null);
+        deque.push(isA(BasicAttributeContext.class));
+
+        replay(applicationContext, attributeEvaluatorFactory,
+                definitionsFactory, preparerFactory, rendererFactory, request,
+                requestScope, deque, attributeContext);
+        assertTrue(container.startContext(request) instanceof BasicAttributeContext);
+        verify(applicationContext, attributeEvaluatorFactory,
+                definitionsFactory, preparerFactory, rendererFactory, request,
+                requestScope, deque, attributeContext);
+    }
+
+    /**
+     * Test method for {@link BasicTilesContainer#endContext(Request)}.
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testEndContext() {
+        Request request = createMock(Request.class);
+        Map<String, Object> requestScope = createMock(Map.class);
+        Deque<AttributeContext> deque = createMock(Deque.class);
+        AttributeContext attributeContext = createMock(AttributeContext.class);
+
+        expect(request.getContext("request")).andReturn(requestScope);
+        expect(requestScope.get(ATTRIBUTE_CONTEXT_STACK)).andReturn(deque);
+        expect(deque.pop()).andReturn(attributeContext);
+
+        replay(applicationContext, attributeEvaluatorFactory,
+                definitionsFactory, preparerFactory, rendererFactory, request,
+                requestScope, deque, attributeContext);
+        container.endContext(request);
+        verify(applicationContext, attributeEvaluatorFactory,
+                definitionsFactory, preparerFactory, rendererFactory, request,
+                requestScope, deque, attributeContext);
+    }
+
+    /**
+     * Test method for {@link BasicTilesContainer#renderContext(Request)}.
+     * @throws IOException If something goes wrong.
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testRenderContext() throws IOException {
+        Request request = createMock(Request.class);
+        Map<String, Object> requestScope = createMock(Map.class);
+        Deque<AttributeContext> deque = createMock(Deque.class);
+        AttributeContext attributeContext = createMock(AttributeContext.class);
+        ViewPreparer preparer = createMock(ViewPreparer.class);
+        Attribute templateAttribute = createMock(Attribute.class);
+        Renderer renderer = createMock(Renderer.class);
+        AttributeEvaluator evaluator = createMock(AttributeEvaluator.class);
+
+        expect(request.getContext("request")).andReturn(requestScope);
+        expect(requestScope.get(ATTRIBUTE_CONTEXT_STACK)).andReturn(deque);
+        expect(deque.isEmpty()).andReturn(false);
+        expect(deque.peek()).andReturn(attributeContext);
+        expect(attributeContext.getPreparer()).andReturn(null);
+        expect(attributeContext.getTemplateAttribute()).andReturn(templateAttribute);
+        expect(templateAttribute.getRenderer()).andReturn("renderer");
+        expect(rendererFactory.getRenderer("renderer")).andReturn(renderer);
+        expect(attributeEvaluatorFactory.getAttributeEvaluator(templateAttribute)).andReturn(evaluator);
+        expect(evaluator.evaluate(templateAttribute, request)).andReturn("/mytemplate.jsp");
+        expect(templateAttribute.isPermitted(request)).andReturn(true);
+        renderer.render("/mytemplate.jsp", request);
+
+        replay(applicationContext, attributeEvaluatorFactory, evaluator,
+                definitionsFactory, preparerFactory, rendererFactory, request,
+                requestScope, deque, attributeContext, preparer, templateAttribute, renderer);
+        container.renderContext(request);
+        verify(applicationContext, attributeEvaluatorFactory, evaluator,
+                definitionsFactory, preparerFactory, rendererFactory, request,
+                requestScope, deque, attributeContext, preparer, templateAttribute, renderer);
+    }
+
+    /**
+     * Test method for {@link BasicTilesContainer#getApplicationContext()}.
+     */
+    @Test
+    public void testGetApplicationContext() {
+        replay(applicationContext, attributeEvaluatorFactory,
+                definitionsFactory, preparerFactory, rendererFactory);
+        assertEquals(applicationContext, container.getApplicationContext());
+        verify(applicationContext, attributeEvaluatorFactory,
+                definitionsFactory, preparerFactory, rendererFactory);
+    }
+
+    /**
+     * Test method for {@link BasicTilesContainer#getAttributeContext(Request)}.
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testGetAttributeContext() {
+        Request request = createMock(Request.class);
+        Map<String, Object> requestScope = createMock(Map.class);
+        Deque<AttributeContext> deque = createMock(Deque.class);
+        AttributeContext attributeContext = createMock(AttributeContext.class);
+
+        expect(request.getContext("request")).andReturn(requestScope);
+        expect(requestScope.get(ATTRIBUTE_CONTEXT_STACK)).andReturn(deque);
+        expect(deque.isEmpty()).andReturn(false);
+        expect(deque.peek()).andReturn(attributeContext);
+
+        replay(applicationContext, attributeEvaluatorFactory,
+                definitionsFactory, preparerFactory, rendererFactory, request,
+                requestScope, deque, attributeContext);
+        assertEquals(attributeContext, container.getAttributeContext(request));
+        verify(applicationContext, attributeEvaluatorFactory,
+                definitionsFactory, preparerFactory, rendererFactory, request,
+                requestScope, deque, attributeContext);
+    }
+
+    /**
+     * Test method for {@link BasicTilesContainer#getAttributeContext(Request)}.
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testGetAttributeContextNew() {
+        Request request = createMock(Request.class);
+        Map<String, Object> requestScope = createMock(Map.class);
+        Deque<AttributeContext> deque = createMock(Deque.class);
+        AttributeContext attributeContext = createMock(AttributeContext.class);
+
+        expect(request.getContext("request")).andReturn(requestScope).times(2);
+        expect(requestScope.get(ATTRIBUTE_CONTEXT_STACK)).andReturn(deque).times(2);
+        expect(deque.isEmpty()).andReturn(true);
+        deque.push(isA(BasicAttributeContext.class));
+
+        replay(applicationContext, attributeEvaluatorFactory,
+                definitionsFactory, preparerFactory, rendererFactory, request,
+                requestScope, deque, attributeContext);
+        assertTrue(container.getAttributeContext(request) instanceof BasicAttributeContext);
+        verify(applicationContext, attributeEvaluatorFactory,
+                definitionsFactory, preparerFactory, rendererFactory, request,
+                requestScope, deque, attributeContext);
+    }
+
+    /**
+     * Test method for {@link BasicTilesContainer#getDefinitionsFactory()}.
+     */
+    @Test
+    public void testGetDefinitionsFactory() {
+        replay(applicationContext, attributeEvaluatorFactory,
+                definitionsFactory, preparerFactory, rendererFactory);
+        assertEquals(definitionsFactory, container.getDefinitionsFactory());
+        verify(applicationContext, attributeEvaluatorFactory,
+                definitionsFactory, preparerFactory, rendererFactory);
+    }
+
+    /**
+     * Test method for {@link BasicTilesContainer#getPreparerFactory()}.
+     */
+    @Test
+    public void testGetPreparerFactory() {
+        replay(applicationContext, attributeEvaluatorFactory,
+                definitionsFactory, preparerFactory, rendererFactory);
+        assertEquals(preparerFactory, container.getPreparerFactory());
+        verify(applicationContext, attributeEvaluatorFactory,
+                definitionsFactory, preparerFactory, rendererFactory);
+    }
+
+    /**
+     * Test method for {@link BasicTilesContainer#prepare(java.lang.String, Request)}.
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testPrepare() {
+        Request request = createMock(Request.class);
+        Map<String, Object> requestScope = createMock(Map.class);
+        Deque<AttributeContext> deque = createMock(Deque.class);
+        AttributeContext attributeContext = createMock(AttributeContext.class);
+        ViewPreparer preparer = createMock(ViewPreparer.class);
+
+        expect(preparerFactory.getPreparer("preparer", request)).andReturn(preparer);
+        expect(request.getContext("request")).andReturn(requestScope);
+        expect(requestScope.get(ATTRIBUTE_CONTEXT_STACK)).andReturn(deque);
+        expect(deque.isEmpty()).andReturn(false);
+        expect(deque.peek()).andReturn(attributeContext);
+        preparer.execute(request, attributeContext);
+
+        replay(applicationContext, attributeEvaluatorFactory,
+                definitionsFactory, preparerFactory, rendererFactory, request,
+                requestScope, deque, attributeContext, preparer);
+        container.prepare("preparer", request);
+        verify(applicationContext, attributeEvaluatorFactory,
+                definitionsFactory, preparerFactory, rendererFactory, request,
+                requestScope, deque, attributeContext, preparer);
+    }
+
+    /**
+     * Test method for {@link BasicTilesContainer#prepare(java.lang.String, Request)}.
+     */
+    @SuppressWarnings("unchecked")
+    @Test(expected = NoSuchPreparerException.class)
+    public void testPrepareException() {
+        Request request = createMock(Request.class);
+        Map<String, Object> requestScope = createMock(Map.class);
+        Deque<AttributeContext> deque = createMock(Deque.class);
+        AttributeContext attributeContext = createMock(AttributeContext.class);
+
+        expect(preparerFactory.getPreparer("preparer", request)).andReturn(null);
+
+        replay(applicationContext, attributeEvaluatorFactory,
+                definitionsFactory, preparerFactory, rendererFactory, request,
+                requestScope, deque, attributeContext);
+        try {
+            container.prepare("preparer", request);
+        } finally {
+            verify(applicationContext, attributeEvaluatorFactory,
+                    definitionsFactory, preparerFactory, rendererFactory,
+                    request, requestScope, deque, attributeContext);
+        }
+    }
+
+    /**
+     * Test method for {@link BasicTilesContainer#render(Request, java.lang.String)}.
+     * @throws IOException If something goes wrong.
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testRenderStringRequest() throws IOException {
+        Request request = createMock(Request.class);
+        Map<String, Object> requestScope = createMock(Map.class);
+        Deque<AttributeContext> deque = createMock(Deque.class);
+        AttributeContext attributeContext = createMock(AttributeContext.class);
+        ViewPreparer preparer = createMock(ViewPreparer.class);
+        Renderer renderer = createMock(Renderer.class);
+        Definition definition = createMock(Definition.class);
+        AttributeEvaluator evaluator = createMock(AttributeEvaluator.class);
+
+        Attribute templateAttribute = Attribute.createTemplateAttribute("/my/template.jsp");
+
+        expect(definitionsFactory.getDefinition("definition", request)).andReturn(definition);
+        expect(request.getContext("request")).andReturn(requestScope).times(3);
+        expect(requestScope.get(ATTRIBUTE_CONTEXT_STACK)).andReturn(deque).times(3);
+        expect(deque.isEmpty()).andReturn(false);
+        expect(deque.peek()).andReturn(attributeContext);
+        expect(attributeContext.getPreparer()).andReturn(null);
+        expect(attributeContext.getTemplateAttribute()).andReturn(templateAttribute);
+        expect(attributeContext.getLocalAttributeNames()).andReturn(null);
+        expect(attributeContext.getCascadedAttributeNames()).andReturn(null);
+        expect(definition.getTemplateAttribute()).andReturn(templateAttribute);
+        expect(rendererFactory.getRenderer("template")).andReturn(renderer);
+        deque.push(isA(BasicAttributeContext.class));
+        expect(attributeEvaluatorFactory.getAttributeEvaluator(templateAttribute)).andReturn(evaluator);
+        expect(evaluator.evaluate(templateAttribute, request)).andReturn("/my/template.jsp");
+        renderer.render("/my/template.jsp", request);
+        expect(deque.pop()).andReturn(null);
+
+        replay(applicationContext, attributeEvaluatorFactory, evaluator,
+                definitionsFactory, preparerFactory, rendererFactory, request,
+                requestScope, deque, attributeContext, preparer, renderer, definition);
+        container.render("definition", request);
+        verify(applicationContext, attributeEvaluatorFactory, evaluator,
+                definitionsFactory, preparerFactory, rendererFactory, request,
+                requestScope, deque, attributeContext, preparer, renderer, definition);
+    }
+
+    /**
+     * Test method for {@link BasicTilesContainer#render(Request, java.lang.String)}.
+     */
+    @Test(expected = NoSuchDefinitionException.class)
+    public void testRenderStringRequestException() {
+        Request request = createMock(Request.class);
+
+        expect(definitionsFactory.getDefinition("definition", request)).andReturn(null);
+
+        replay(applicationContext, attributeEvaluatorFactory,
+                definitionsFactory, preparerFactory, rendererFactory, request);
+        try {
+            container.render("definition", request);
+        } finally {
+            verify(applicationContext, attributeEvaluatorFactory,
+                    definitionsFactory, preparerFactory, rendererFactory);
+        }
+    }
+
+    /**
+     * Test method for {@link BasicTilesContainer#render(Request, org.apache.tiles.Attribute)}.
+     * @throws IOException If something goes wrong.
+     */
+    @Test
+    public void testRenderAttributeRequest() throws IOException {
+        Request request = createMock(Request.class);
+        Attribute templateAttribute = createMock(Attribute.class);
+        Renderer renderer = createMock(Renderer.class);
+        AttributeEvaluator evaluator = createMock(AttributeEvaluator.class);
+
+        expect(templateAttribute.getRenderer()).andReturn("renderer");
+        expect(rendererFactory.getRenderer("renderer")).andReturn(renderer);
+        expect(attributeEvaluatorFactory.getAttributeEvaluator(templateAttribute)).andReturn(evaluator);
+        expect(evaluator.evaluate(templateAttribute, request)).andReturn("/mytemplate.jsp");
+        expect(templateAttribute.isPermitted(request)).andReturn(true);
+        renderer.render("/mytemplate.jsp", request);
+
+        replay(applicationContext, attributeEvaluatorFactory, evaluator,
+                definitionsFactory, preparerFactory, rendererFactory, request,
+                templateAttribute, renderer);
+        container.render(templateAttribute, request);
+        verify(applicationContext, attributeEvaluatorFactory, evaluator,
+                definitionsFactory, preparerFactory, rendererFactory, request,
+                templateAttribute, renderer);
+    }
+
+    /**
+     * Test method for {@link BasicTilesContainer#render(Request, org.apache.tiles.Attribute)}.
+     * @throws IOException If something goes wrong.
+     */
+    @Test(expected = CannotRenderException.class)
+    public void testRenderAttributeRequestException1() throws IOException {
+        Request request = createMock(Request.class);
+
+        replay(applicationContext, attributeEvaluatorFactory,
+                definitionsFactory, preparerFactory, rendererFactory, request);
+        try {
+            container.render((Attribute) null, request);
+        } finally {
+            verify(applicationContext, attributeEvaluatorFactory,
+                    definitionsFactory, preparerFactory, rendererFactory,
+                    request);
+        }
+    }
+
+    /**
+     * Test method for {@link BasicTilesContainer#render(Request, org.apache.tiles.Attribute)}.
+     * @throws IOException If something goes wrong.
+     */
+    @Test(expected = NoSuchRendererException.class)
+    public void testRenderAttributeRequestException2() throws IOException {
+        Request request = createMock(Request.class);
+        Attribute templateAttribute = createMock(Attribute.class);
+        AttributeEvaluator evaluator = createMock(AttributeEvaluator.class);
+
+        expect(templateAttribute.getRenderer()).andReturn("renderer");
+        expect(templateAttribute.isPermitted(request)).andReturn(true);
+        expect(rendererFactory.getRenderer("renderer")).andThrow(new NoSuchRendererException());
+
+        replay(applicationContext, attributeEvaluatorFactory, evaluator,
+                definitionsFactory, preparerFactory, rendererFactory, request,
+                templateAttribute);
+        try {
+            container.render(templateAttribute, request);
+        } finally {
+            verify(applicationContext, attributeEvaluatorFactory, evaluator,
+                    definitionsFactory, preparerFactory, rendererFactory,
+                    request, templateAttribute);
+        }
+    }
+
+    /**
+     * Test method for {@link BasicTilesContainer#render(Request, org.apache.tiles.Attribute)}.
+     * @throws IOException If something goes wrong.
+     */
+    @Test(expected = CannotRenderException.class)
+    public void testRenderAttributeRequestException3() throws IOException {
+        Request request = createMock(Request.class);
+        Attribute templateAttribute = createMock(Attribute.class);
+        AttributeEvaluator evaluator = createMock(AttributeEvaluator.class);
+        Renderer renderer = createMock(Renderer.class);
+
+        expect(templateAttribute.getRenderer()).andReturn("renderer");
+        expect(templateAttribute.isPermitted(request)).andReturn(true);
+        expect(rendererFactory.getRenderer("renderer")).andReturn(renderer);
+        expect(attributeEvaluatorFactory.getAttributeEvaluator(templateAttribute)).andReturn(evaluator);
+        expect(evaluator.evaluate(templateAttribute, request)).andReturn(new Integer(1));
+
+        replay(applicationContext, attributeEvaluatorFactory, evaluator,
+                definitionsFactory, preparerFactory, rendererFactory, request,
+                templateAttribute);
+        try {
+            container.render(templateAttribute, request);
+        } finally {
+            verify(applicationContext, attributeEvaluatorFactory, evaluator,
+                    definitionsFactory, preparerFactory, rendererFactory,
+                    request, templateAttribute);
+        }
+    }
+
+    /**
+     * Test method for {@link BasicTilesContainer#render(Request, org.apache.tiles.Attribute)}.
+     * @throws IOException If something goes wrong.
+     */
+    @Test(expected = NoSuchRendererException.class)
+    public void testRenderAttributeRequestException() throws IOException {
+        Request request = createMock(Request.class);
+        Attribute templateAttribute = createMock(Attribute.class);
+        AttributeEvaluator evaluator = createMock(AttributeEvaluator.class);
+
+        expect(templateAttribute.getRenderer()).andReturn("renderer");
+        expect(templateAttribute.isPermitted(request)).andReturn(true);
+        expect(rendererFactory.getRenderer("renderer")).andThrow(new NoSuchRendererException());
+
+        replay(applicationContext, attributeEvaluatorFactory, evaluator,
+                definitionsFactory, preparerFactory, rendererFactory, request,
+                templateAttribute);
+        try {
+            container.render(templateAttribute, request);
+        } finally {
+            verify(applicationContext, attributeEvaluatorFactory, evaluator,
+                    definitionsFactory, preparerFactory, rendererFactory,
+                    request, templateAttribute);
+        }
+    }
+
+    /**
+     * Test method for {@link BasicTilesContainer#evaluate(org.apache.tiles.Attribute, Request)}.
+     */
+    @Test
+    public void testEvaluate() {
+        Request request = createMock(Request.class);
+        AttributeEvaluator evaluator = createMock(AttributeEvaluator.class);
+        Attribute templateAttribute = createMock(Attribute.class);
+
+        expect(attributeEvaluatorFactory.getAttributeEvaluator(templateAttribute)).andReturn(evaluator);
+        expect(evaluator.evaluate(templateAttribute, request)).andReturn(new Integer(1));
+
+        replay(applicationContext, attributeEvaluatorFactory,
+                definitionsFactory, preparerFactory, rendererFactory, request,
+                templateAttribute, evaluator);
+        assertEquals(new Integer(1), container.evaluate(templateAttribute, request));
+        verify(applicationContext, attributeEvaluatorFactory,
+                definitionsFactory, preparerFactory, rendererFactory, request,
+                templateAttribute, evaluator);
+    }
+
+    /**
+     * Test method for {@link BasicTilesContainer#isValidDefinition(java.lang.String, Request)}.
+     */
+    @Test
+    public void testIsValidDefinition() {
+        Request request = createMock(Request.class);
+        Definition definition = createMock(Definition.class);
+
+        expect(definitionsFactory.getDefinition("definition", request)).andReturn(definition);
+
+        replay(applicationContext, attributeEvaluatorFactory,
+                definitionsFactory, preparerFactory, rendererFactory, request, definition);
+        assertTrue(container.isValidDefinition("definition", request));
+        verify(applicationContext, attributeEvaluatorFactory,
+                definitionsFactory, preparerFactory, rendererFactory, request, definition);
+    }
+
+    /**
+     * Test method for {@link BasicTilesContainer#isValidDefinition(java.lang.String, Request)}.
+     */
+    @Test
+    public void testIsValidDefinitionNull() {
+        Request request = createMock(Request.class);
+
+        expect(definitionsFactory.getDefinition("definition", request)).andReturn(null);
+
+        replay(applicationContext, attributeEvaluatorFactory,
+                definitionsFactory, preparerFactory, rendererFactory, request);
+        assertFalse(container.isValidDefinition("definition", request));
+        verify(applicationContext, attributeEvaluatorFactory,
+                definitionsFactory, preparerFactory, rendererFactory, request);
+    }
+
+    /**
+     * Test method for {@link BasicTilesContainer#isValidDefinition(java.lang.String, Request)}.
+     */
+    @Test
+    public void testIsValidDefinitionException() {
+        Request request = createMock(Request.class);
+
+        expect(definitionsFactory.getDefinition("definition", request))
+                .andThrow(new NoSuchDefinitionException());
+
+        replay(applicationContext, attributeEvaluatorFactory,
+                definitionsFactory, preparerFactory, rendererFactory, request);
+        assertFalse(container.isValidDefinition("definition", request));
+        verify(applicationContext, attributeEvaluatorFactory,
+                definitionsFactory, preparerFactory, rendererFactory, request);
+    }
+
+    /**
+     * Test method for {@link BasicTilesContainer#getDefinition(java.lang.String, Request)}.
+     */
+    @Test
+    public void testGetDefinition() {
+        Request request = createMock(Request.class);
+        Definition definition = createMock(Definition.class);
+
+        expect(definitionsFactory.getDefinition("definition", request)).andReturn(definition);
+
+        replay(applicationContext, attributeEvaluatorFactory,
+                definitionsFactory, preparerFactory, rendererFactory, request, definition);
+        assertEquals(definition, container.getDefinition("definition", request));
+        verify(applicationContext, attributeEvaluatorFactory,
+                definitionsFactory, preparerFactory, rendererFactory, request, definition);
+    }
+
+    /**
+     * Test method for {@link BasicTilesContainer#getContextStack(Request)}.
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testGetContextStack() {
+        Request request = createMock(Request.class);
+        Map<String, Object> requestScope = createMock(Map.class);
+        Deque<AttributeContext> deque = createMock(Deque.class);
+
+        expect(request.getContext("request")).andReturn(requestScope);
+        expect(requestScope.get(ATTRIBUTE_CONTEXT_STACK)).andReturn(deque);
+
+        replay(applicationContext, attributeEvaluatorFactory,
+                definitionsFactory, preparerFactory, rendererFactory, request,
+                requestScope, deque);
+        assertEquals(deque, container.getContextStack(request));
+        verify(applicationContext, attributeEvaluatorFactory,
+                definitionsFactory, preparerFactory, rendererFactory, request,
+                requestScope, deque);
+    }
+
+    /**
+     * Test method for {@link BasicTilesContainer#getContextStack(Request)}.
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testGetContextStackNew() {
+        Request request = createMock(Request.class);
+        Map<String, Object> requestScope = createMock(Map.class);
+
+        expect(request.getContext("request")).andReturn(requestScope);
+        expect(requestScope.get(ATTRIBUTE_CONTEXT_STACK)).andReturn(null);
+        expect(requestScope.put(eq(ATTRIBUTE_CONTEXT_STACK), isA(LinkedList.class))).andReturn(null);
+
+        replay(applicationContext, attributeEvaluatorFactory,
+                definitionsFactory, preparerFactory, rendererFactory, request,
+                requestScope);
+        assertTrue(container.getContextStack(request) instanceof LinkedList);
+        verify(applicationContext, attributeEvaluatorFactory,
+                definitionsFactory, preparerFactory, rendererFactory, request,
+                requestScope);
+    }
+
+    /**
+     * Test method for {@link BasicTilesContainer#pushContext(org.apache.tiles.AttributeContext, Request)}.
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testPushContext() {
+        Request request = createMock(Request.class);
+        Map<String, Object> requestScope = createMock(Map.class);
+        Deque<AttributeContext> deque = createMock(Deque.class);
+        AttributeContext attributeContext = createMock(AttributeContext.class);
+
+        expect(request.getContext("request")).andReturn(requestScope);
+        expect(requestScope.get(ATTRIBUTE_CONTEXT_STACK)).andReturn(deque);
+        deque.push(attributeContext);
+
+        replay(applicationContext, attributeEvaluatorFactory,
+                definitionsFactory, preparerFactory, rendererFactory, request,
+                requestScope, deque, attributeContext);
+        container.pushContext(attributeContext, request);
+        verify(applicationContext, attributeEvaluatorFactory,
+                definitionsFactory, preparerFactory, rendererFactory, request,
+                requestScope, deque, attributeContext);
+    }
+
+    /**
+     * Test method for {@link BasicTilesContainer#popContext(Request)}.
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testPopContext() {
+        Request request = createMock(Request.class);
+        Map<String, Object> requestScope = createMock(Map.class);
+        Deque<AttributeContext> deque = createMock(Deque.class);
+        AttributeContext attributeContext = createMock(AttributeContext.class);
+
+        expect(request.getContext("request")).andReturn(requestScope);
+        expect(requestScope.get(ATTRIBUTE_CONTEXT_STACK)).andReturn(deque);
+        expect(deque.pop()).andReturn(attributeContext);
+
+        replay(applicationContext, attributeEvaluatorFactory,
+                definitionsFactory, preparerFactory, rendererFactory, request,
+                requestScope, deque, attributeContext);
+        assertEquals(attributeContext, container.popContext(request));
+        verify(applicationContext, attributeEvaluatorFactory,
+                definitionsFactory, preparerFactory, rendererFactory, request,
+                requestScope, deque, attributeContext);
+    }
+
+    /**
+     * Test method for {@link BasicTilesContainer#getContext(Request)}.
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testGetContext() {
+        Request request = createMock(Request.class);
+        Map<String, Object> requestScope = createMock(Map.class);
+        Deque<AttributeContext> deque = createMock(Deque.class);
+        AttributeContext attributeContext = createMock(AttributeContext.class);
+
+        expect(request.getContext("request")).andReturn(requestScope);
+        expect(requestScope.get(ATTRIBUTE_CONTEXT_STACK)).andReturn(deque);
+        expect(deque.isEmpty()).andReturn(false);
+        expect(deque.peek()).andReturn(attributeContext);
+
+        replay(applicationContext, attributeEvaluatorFactory,
+                definitionsFactory, preparerFactory, rendererFactory, request,
+                requestScope, deque, attributeContext);
+        assertEquals(attributeContext, container.getContext(request));
+        verify(applicationContext, attributeEvaluatorFactory,
+                definitionsFactory, preparerFactory, rendererFactory, request,
+                requestScope, deque, attributeContext);
+    }
+
+    /**
+     * Test method for {@link BasicTilesContainer#getContext(Request)}.
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testGetContextNull() {
+        Request request = createMock(Request.class);
+        Map<String, Object> requestScope = createMock(Map.class);
+        Deque<AttributeContext> deque = createMock(Deque.class);
+
+        expect(request.getContext("request")).andReturn(requestScope);
+        expect(requestScope.get(ATTRIBUTE_CONTEXT_STACK)).andReturn(deque);
+        expect(deque.isEmpty()).andReturn(true);
+
+        replay(applicationContext, attributeEvaluatorFactory,
+                definitionsFactory, preparerFactory, rendererFactory, request,
+                requestScope, deque);
+        assertNull(container.getContext(request));
+        verify(applicationContext, attributeEvaluatorFactory,
+                definitionsFactory, preparerFactory, rendererFactory, request,
+                requestScope, deque);
+    }
+
+    /**
+     * Test method for {@link BasicTilesContainer#render(org.apache.tiles.Definition, Request)}.
+     * @throws IOException If something goes wrong.
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testRenderRequestDefinition() throws IOException {
+        Request request = createMock(Request.class);
+        Map<String, Object> requestScope = createMock(Map.class);
+        Deque<AttributeContext> deque = createMock(Deque.class);
+        AttributeContext attributeContext = createMock(AttributeContext.class);
+        ViewPreparer preparer = createMock(ViewPreparer.class);
+        Renderer renderer = createMock(Renderer.class);
+        Definition definition = createMock(Definition.class);
+        AttributeEvaluator evaluator = createMock(AttributeEvaluator.class);
+
+        Attribute templateAttribute = Attribute.createTemplateAttribute("/my/template.jsp");
+
+        expect(request.getContext("request")).andReturn(requestScope).times(3);
+        expect(requestScope.get(ATTRIBUTE_CONTEXT_STACK)).andReturn(deque).times(3);
+        expect(deque.isEmpty()).andReturn(false);
+        expect(deque.peek()).andReturn(attributeContext);
+        expect(attributeContext.getPreparer()).andReturn(null);
+        expect(attributeContext.getTemplateAttribute()).andReturn(templateAttribute);
+        expect(attributeContext.getLocalAttributeNames()).andReturn(null);
+        expect(attributeContext.getCascadedAttributeNames()).andReturn(null);
+        expect(definition.getTemplateAttribute()).andReturn(templateAttribute);
+        expect(rendererFactory.getRenderer("template")).andReturn(renderer);
+        deque.push(isA(BasicAttributeContext.class));
+        expect(attributeEvaluatorFactory.getAttributeEvaluator(templateAttribute)).andReturn(evaluator);
+        expect(evaluator.evaluate(templateAttribute, request)).andReturn("/my/template.jsp");
+        renderer.render("/my/template.jsp", request);
+        expect(deque.pop()).andReturn(null);
+
+        replay(applicationContext, attributeEvaluatorFactory, evaluator,
+                definitionsFactory, preparerFactory, rendererFactory, request,
+                requestScope, deque, attributeContext, preparer, renderer, definition);
+        container.render(definition, request);
+        verify(applicationContext, attributeEvaluatorFactory, evaluator,
+                definitionsFactory, preparerFactory, rendererFactory, request,
+                requestScope, deque, attributeContext, preparer, renderer, definition);
+    }
+
+    /**
+     * Test method for {@link BasicTilesContainer#render(org.apache.tiles.Definition, Request)}.
+     * @throws IOException If something goes wrong.
+     */
+    @SuppressWarnings("unchecked")
+    @Test(expected = CannotRenderException.class)
+    public void testRenderRequestDefinitionException() throws IOException {
+        Request request = createMock(Request.class);
+        Map<String, Object> requestScope = createMock(Map.class);
+        Deque<AttributeContext> deque = createMock(Deque.class);
+        AttributeContext attributeContext = createMock(AttributeContext.class);
+        ViewPreparer preparer = createMock(ViewPreparer.class);
+        Renderer renderer = createMock(Renderer.class);
+        Definition definition = createMock(Definition.class);
+        AttributeEvaluator evaluator = createMock(AttributeEvaluator.class);
+
+        Attribute templateAttribute = Attribute.createTemplateAttribute("/my/template.jsp");
+
+        expect(request.getContext("request")).andReturn(requestScope).times(3);
+        expect(requestScope.get(ATTRIBUTE_CONTEXT_STACK)).andReturn(deque).times(3);
+        expect(deque.isEmpty()).andReturn(false);
+        expect(deque.peek()).andReturn(attributeContext);
+        expect(attributeContext.getPreparer()).andReturn(null);
+        expect(attributeContext.getTemplateAttribute()).andReturn(templateAttribute);
+        expect(attributeContext.getLocalAttributeNames()).andReturn(null);
+        expect(attributeContext.getCascadedAttributeNames()).andReturn(null);
+        expect(definition.getTemplateAttribute()).andReturn(templateAttribute);
+        expect(rendererFactory.getRenderer("template")).andReturn(renderer);
+        deque.push(isA(BasicAttributeContext.class));
+        expect(attributeEvaluatorFactory.getAttributeEvaluator(templateAttribute)).andReturn(evaluator);
+        expect(evaluator.evaluate(templateAttribute, request)).andReturn("/mytemplate.jsp");
+        renderer.render("/mytemplate.jsp", request);
+        expectLastCall().andThrow(new IOException());
+        expect(deque.pop()).andReturn(null);
+
+        replay(applicationContext, attributeEvaluatorFactory, evaluator,
+                definitionsFactory, preparerFactory, rendererFactory, request,
+                requestScope, deque, attributeContext, preparer, renderer, definition);
+        try {
+            container.render(definition, request);
+        } finally {
+            verify(applicationContext, attributeEvaluatorFactory, evaluator,
+                    definitionsFactory, preparerFactory, rendererFactory,
+                    request, requestScope, deque, attributeContext, preparer,
+                    renderer, definition);
+        }
+    }
+
+    /**
+     * Test method for {@link BasicTilesContainer#render(Request, org.apache.tiles.AttributeContext)}.
+     * @throws IOException If something goes wrong.
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testRenderRequestAttributeContext() throws IOException {
+        Request request = createMock(Request.class);
+        Map<String, Object> requestScope = createMock(Map.class);
+        Deque<AttributeContext> deque = createMock(Deque.class);
+        AttributeContext attributeContext = createMock(AttributeContext.class);
+        ViewPreparer preparer = createMock(ViewPreparer.class);
+        Attribute templateAttribute = createMock(Attribute.class);
+        Renderer renderer = createMock(Renderer.class);
+        AttributeEvaluator evaluator = createMock(AttributeEvaluator.class);
+
+        expect(attributeContext.getPreparer()).andReturn(null);
+        expect(attributeContext.getTemplateAttribute()).andReturn(templateAttribute);
+        expect(templateAttribute.getRenderer()).andReturn("renderer");
+        expect(rendererFactory.getRenderer("renderer")).andReturn(renderer);
+        expect(attributeEvaluatorFactory.getAttributeEvaluator(templateAttribute)).andReturn(evaluator);
+        expect(evaluator.evaluate(templateAttribute, request)).andReturn("/mytemplate.jsp");
+        expect(templateAttribute.isPermitted(request)).andReturn(true);
+        renderer.render("/mytemplate.jsp", request);
+
+        replay(applicationContext, attributeEvaluatorFactory, evaluator,
+                definitionsFactory, preparerFactory, rendererFactory, request,
+                requestScope, deque, attributeContext, preparer, templateAttribute, renderer);
+        container.render(request, attributeContext);
+        verify(applicationContext, attributeEvaluatorFactory, evaluator,
+                definitionsFactory, preparerFactory, rendererFactory, request,
+                requestScope, deque, attributeContext, preparer, templateAttribute, renderer);
+    }
+
+    /**
+     * Test method for {@link BasicTilesContainer#render(Request, org.apache.tiles.AttributeContext)}.
+     * @throws IOException If something goes wrong.
+     */
+    @SuppressWarnings("unchecked")
+    @Test(expected = CannotRenderException.class)
+    public void testRenderRequestAttributeContextException() throws IOException {
+        Request request = createMock(Request.class);
+        Map<String, Object> requestScope = createMock(Map.class);
+        Deque<AttributeContext> deque = createMock(Deque.class);
+        AttributeContext attributeContext = createMock(AttributeContext.class);
+        Attribute templateAttribute = createMock(Attribute.class);
+        Renderer renderer = createMock(Renderer.class);
+        AttributeEvaluator evaluator = createMock(AttributeEvaluator.class);
+
+        expect(attributeContext.getPreparer()).andReturn("preparer").times(2);
+        expect(preparerFactory.getPreparer("preparer", request)).andReturn(null);
+        expect(attributeContext.getTemplateAttribute()).andReturn(templateAttribute);
+        expect(templateAttribute.getRenderer()).andReturn("renderer");
+        expect(rendererFactory.getRenderer("renderer")).andReturn(renderer);
+        expect(attributeEvaluatorFactory.getAttributeEvaluator(templateAttribute)).andReturn(evaluator);
+        expect(evaluator.evaluate(templateAttribute, request)).andReturn("/mytemplate.jsp");
+        expect(templateAttribute.isPermitted(request)).andReturn(true);
+        renderer.render("/mytemplate.jsp", request);
+        expectLastCall().andThrow(new IOException());
+
+        replay(applicationContext, attributeEvaluatorFactory, evaluator,
+                definitionsFactory, preparerFactory, rendererFactory, request,
+                requestScope, deque, attributeContext, templateAttribute, renderer);
+        try {
+            container.render(request, attributeContext);
+        } finally {
+            verify(applicationContext, attributeEvaluatorFactory, evaluator,
+                    definitionsFactory, preparerFactory, rendererFactory,
+                    request, requestScope, deque, attributeContext,
+                    templateAttribute, renderer);
+        }
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/impl/CannotRenderExceptionTest.java b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/impl/CannotRenderExceptionTest.java
new file mode 100644
index 000000000..6e7c768ff
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/impl/CannotRenderExceptionTest.java
@@ -0,0 +1,78 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.impl;
+
+import static org.junit.Assert.*;
+
+import org.apache.tiles.request.render.CannotRenderException;
+import org.junit.Test;
+
+/**
+ * Tests {@link CannotRenderException}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class CannotRenderExceptionTest {
+
+    /**
+     * Test method for {@link CannotRenderException#CannotRenderException()}.
+     */
+    @Test
+    public void testCannotRenderException() {
+        CannotRenderException exception = new CannotRenderException();
+        assertNull(exception.getMessage());
+        assertNull(exception.getCause());
+    }
+
+    /**
+     * Test method for {@link CannotRenderException#CannotRenderException(java.lang.String)}.
+     */
+    @Test
+    public void testCannotRenderExceptionString() {
+        CannotRenderException exception = new CannotRenderException("my message");
+        assertEquals("my message", exception.getMessage());
+        assertNull(exception.getCause());
+    }
+
+    /**
+     * Test method for {@link CannotRenderException#CannotRenderException(java.lang.Throwable)}.
+     */
+    @Test
+    public void testCannotRenderExceptionThrowable() {
+        Throwable cause = new Throwable();
+        CannotRenderException exception = new CannotRenderException(cause);
+        assertEquals(cause.toString(), exception.getMessage());
+        assertEquals(cause, exception.getCause());
+    }
+
+    /**
+     * Test method for {@link CannotRenderException#CannotRenderException(java.lang.String, java.lang.Throwable)}.
+     */
+    @Test
+    public void testCannotRenderExceptionStringThrowable() {
+        Throwable cause = new Throwable();
+        CannotRenderException exception = new CannotRenderException("my message", cause);
+        assertEquals("my message", exception.getMessage());
+        assertEquals(cause, exception.getCause());
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/impl/InvalidTemplateExceptionTest.java b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/impl/InvalidTemplateExceptionTest.java
new file mode 100644
index 000000000..0910d124a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/impl/InvalidTemplateExceptionTest.java
@@ -0,0 +1,77 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.impl;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+/**
+ * Tests {@link InvalidTemplateException}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class InvalidTemplateExceptionTest {
+
+    /**
+     * Test method for {@link InvalidTemplateException#InvalidTemplateException()}.
+     */
+    @Test
+    public void testInvalidTemplateException() {
+        InvalidTemplateException exception = new InvalidTemplateException();
+        assertNull(exception.getMessage());
+        assertNull(exception.getCause());
+    }
+
+    /**
+     * Test method for {@link InvalidTemplateException#InvalidTemplateException(java.lang.String)}.
+     */
+    @Test
+    public void testInvalidTemplateExceptionString() {
+        InvalidTemplateException exception = new InvalidTemplateException("my message");
+        assertEquals("my message", exception.getMessage());
+        assertNull(exception.getCause());
+    }
+
+    /**
+     * Test method for {@link InvalidTemplateException#InvalidTemplateException(java.lang.Throwable)}.
+     */
+    @Test
+    public void testInvalidTemplateExceptionThrowable() {
+        Throwable cause = new Throwable();
+        InvalidTemplateException exception = new InvalidTemplateException(cause);
+        assertEquals(cause.toString(), exception.getMessage());
+        assertEquals(cause, exception.getCause());
+    }
+
+    /**
+     * Test method for {@link InvalidTemplateException#InvalidTemplateException(java.lang.String, java.lang.Throwable)}.
+     */
+    @Test
+    public void testInvalidTemplateExceptionStringThrowable() {
+        Throwable cause = new Throwable();
+        InvalidTemplateException exception = new InvalidTemplateException("my message", cause);
+        assertEquals("my message", exception.getMessage());
+        assertEquals(cause, exception.getCause());
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/impl/mgmt/CachingTilesContainerTest.java b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/impl/mgmt/CachingTilesContainerTest.java
new file mode 100644
index 000000000..befcfdb78
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/impl/mgmt/CachingTilesContainerTest.java
@@ -0,0 +1,402 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.impl.mgmt;
+
+import static org.easymock.EasyMock.*;
+import static org.easymock.classextension.EasyMock.*;
+import static org.junit.Assert.*;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tiles.Definition;
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.definition.NoSuchDefinitionException;
+import org.apache.tiles.request.Request;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests {@link CachingTilesContainer}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class CachingTilesContainerTest {
+
+    /**
+     * The default name of the attribute in which storing custom definitions.
+     */
+    private static final String DEFAULT_DEFINITIONS_ATTRIBUTE_NAME =
+        "org.apache.tiles.impl.mgmt.DefinitionManager.DEFINITIONS";
+
+    /**
+     * The wrapped Tiles container.
+     */
+    private TilesContainer wrapped;
+
+    /**
+     * The Tiles container to test.
+     */
+    private CachingTilesContainer container;
+
+    /**
+     * Sets up the test.
+     */
+    @Before
+    public void setUp() {
+        wrapped = createMock(TilesContainer.class);
+        container = new CachingTilesContainer(wrapped);
+    }
+
+    /**
+     * Test method for
+     * {@link CachingTilesContainer#CachingTilesContainer(TilesContainer, String)}
+     * .
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testCachingTilesContainerTilesContainerString() {
+        TilesContainer wrapped = createMock(TilesContainer.class);
+        Request request = createMock(Request.class);
+        Map<String, Definition> definitions = createMock(Map.class);
+        Map<String, Object> scope = createMock(Map.class);
+        Definition definition = createMock(Definition.class);
+
+        expect(request.getContext("request")).andReturn(scope);
+        expect(scope.get("myattribute")).andReturn(definitions);
+        expect(definitions.get("definition")).andReturn(definition);
+
+        replay(wrapped, request, definitions, scope, definition);
+        CachingTilesContainer container = new CachingTilesContainer(wrapped,
+                "myattribute");
+        assertSame(definition, container.getDefinition("definition", request));
+        verify(wrapped, request, definitions, scope, definition);
+    }
+
+    /**
+     * Test method for
+     * {@link org.apache.tiles.impl.mgmt.CachingTilesContainer#CachingTilesContainer(TilesContainer, String)}
+     * .
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testCachingTilesContainer() {
+        Request request = createMock(Request.class);
+        Map<String, Definition> definitions = createMock(Map.class);
+        Map<String, Object> scope = createMock(Map.class);
+        Definition definition = createMock(Definition.class);
+        TilesContainer wrapped = createMock(TilesContainer.class);
+
+        expect(request.getContext("request")).andReturn(scope);
+        expect(scope.get(DEFAULT_DEFINITIONS_ATTRIBUTE_NAME)).andReturn(
+                definitions);
+        expect(definitions.get("definition")).andReturn(definition);
+
+        replay(wrapped, request, definitions, scope, definition);
+        CachingTilesContainer container = new CachingTilesContainer(wrapped,
+                null);
+        assertSame(definition, container.getDefinition("definition", request));
+        verify(wrapped, request, definitions, scope, definition);
+    }
+
+    /**
+     * Test method for
+     * {@link CachingTilesContainer#getDefinition(String, Request)}
+     * .
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testGetDefinition() {
+        Request request = createMock(Request.class);
+        Map<String, Definition> definitions = createMock(Map.class);
+        Map<String, Object> scope = createMock(Map.class);
+        Definition definition = createMock(Definition.class);
+
+        expect(request.getContext("request")).andReturn(scope);
+        expect(scope.get(DEFAULT_DEFINITIONS_ATTRIBUTE_NAME)).andReturn(
+                definitions);
+        expect(definitions.get("definition")).andReturn(definition);
+
+        replay(wrapped, request, definitions, scope, definition);
+        assertSame(definition, container.getDefinition("definition", request));
+        verify(wrapped, request, definitions, scope, definition);
+    }
+
+    /**
+     * Test method for
+     * {@link CachingTilesContainer#getDefinition(String, Request)}
+     * .
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testGetDefinitionContainer() {
+        Request request = createMock(Request.class);
+        Map<String, Object> scope = createMock(Map.class);
+        Definition definition = createMock(Definition.class);
+
+        expect(request.getContext("request")).andReturn(scope);
+        expect(scope.get(DEFAULT_DEFINITIONS_ATTRIBUTE_NAME)).andReturn(
+                null);
+        expect(wrapped.getDefinition("definition", request)).andReturn(
+                definition);
+
+        replay(wrapped, request, scope, definition);
+        assertSame(definition, container.getDefinition("definition", request));
+        verify(wrapped, request, scope, definition);
+    }
+
+    /**
+     * Test method for
+     * {@link org.apache.tiles.impl.mgmt.CachingTilesContainer#isValidDefinition(String, Request)}
+     * .
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testIsValidDefinition() {
+        Request request = createMock(Request.class);
+        Map<String, Definition> definitions = createMock(Map.class);
+        Map<String, Object> scope = createMock(Map.class);
+        Definition definition = createMock(Definition.class);
+
+        expect(request.getContext("request")).andReturn(scope);
+        expect(scope.get(DEFAULT_DEFINITIONS_ATTRIBUTE_NAME)).andReturn(
+                definitions);
+        expect(definitions.get("definition")).andReturn(definition);
+
+        replay(wrapped, request, definitions, scope, definition);
+        assertTrue(container.isValidDefinition("definition", request));
+        verify(wrapped, request, definitions, scope, definition);
+    }
+
+    /**
+     * Test method for
+     * {@link org.apache.tiles.impl.mgmt.CachingTilesContainer#isValidDefinition(String, Request)}
+     * .
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testIsValidDefinitionContainer() {
+        Request request = createMock(Request.class);
+        Map<String, Definition> definitions = createMock(Map.class);
+        Map<String, Object> scope = createMock(Map.class);
+
+        expect(request.getContext("request")).andReturn(scope);
+        expect(scope.get(DEFAULT_DEFINITIONS_ATTRIBUTE_NAME)).andReturn(
+                definitions);
+        expect(definitions.get("definition")).andReturn(null);
+        expect(wrapped.isValidDefinition("definition", request)).andReturn(true);
+
+        replay(wrapped, request, definitions, scope);
+        assertTrue(container.isValidDefinition("definition", request));
+        verify(wrapped, request, definitions, scope);
+    }
+
+    /**
+     * Test method for
+     * {@link CachingTilesContainer#register(Definition, Request)}
+     * .
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testRegister() {
+        Request request = createMock(Request.class);
+        Map<String, Definition> definitions = createMock(Map.class);
+        Map<String, Object> scope = createMock(Map.class);
+        Definition definition = createMock(Definition.class);
+
+        expect(request.getContext("request")).andReturn(scope);
+        expect(scope.get(DEFAULT_DEFINITIONS_ATTRIBUTE_NAME)).andReturn(
+                definitions);
+        expect(definition.getName()).andReturn(null);
+        expect(definitions.containsKey("$anonymousMutableDefinition1"))
+                .andReturn(false);
+        definition.setName("$anonymousMutableDefinition1");
+        expect(definition.isExtending()).andReturn(true);
+        // trick to test resolve definition separately.
+        expect(definition.isExtending()).andReturn(false);
+        expect(definition.getName()).andReturn("$anonymousMutableDefinition1");
+        expect(definitions.put("$anonymousMutableDefinition1", definition))
+                .andReturn(null);
+
+        replay(wrapped, request, definitions, scope, definition);
+        container.register(definition, request);
+        verify(wrapped, request, definitions, scope, definition);
+    }
+
+    /**
+     * Test method for
+     * {@link CachingTilesContainer#register(Definition, Request)}
+     * .
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testRegisterInheritance() {
+        Request request = createMock(Request.class);
+        Map<String, Definition> definitions = createMock(Map.class);
+        Map<String, Object> scope = createMock(Map.class);
+        Definition definition = createMock(Definition.class);
+        Definition parent = createMock(Definition.class);
+        Definition grandparent = createMock(Definition.class);
+
+        expect(request.getContext("request")).andReturn(scope).anyTimes();
+        expect(scope.get(DEFAULT_DEFINITIONS_ATTRIBUTE_NAME)).andReturn(
+                definitions).anyTimes();
+        expect(definition.getName()).andReturn(null);
+        expect(definitions.containsKey("$anonymousMutableDefinition1"))
+                .andReturn(false);
+        definition.setName("$anonymousMutableDefinition1");
+        expect(definition.isExtending()).andReturn(true);
+        // trick to test resolve definition separately.
+        expect(definition.isExtending()).andReturn(true);
+        expect(definition.getExtends()).andReturn("parent");
+        expect(definitions.get("parent")).andReturn(parent);
+        expect(parent.isExtending()).andReturn(true);
+        expect(parent.getExtends()).andReturn("grandparent");
+        expect(definition.getName()).andReturn("$anonymousMutableDefinition1");
+        expect(definitions.get("grandparent")).andReturn(null);
+        expect(wrapped.getDefinition("grandparent", request)).andReturn(
+                grandparent);
+        parent.inherit(grandparent);
+        definition.inherit(parent);
+        expect(definitions.put("$anonymousMutableDefinition1", definition))
+                .andReturn(null);
+
+        replay(wrapped, request, definitions, scope, definition, parent,
+                grandparent);
+        container.register(definition, request);
+        verify(wrapped, request, definitions, scope, definition, parent,
+                grandparent);
+    }
+
+    /**
+     * Test method for
+     * {@link CachingTilesContainer#register(Definition, Request)}
+     * .
+     */
+    @SuppressWarnings("unchecked")
+    @Test(expected = NoSuchDefinitionException.class)
+    public void testRegisterInheritanceFail() {
+        Request request = createMock(Request.class);
+        Map<String, Definition> definitions = createMock(Map.class);
+        Map<String, Object> scope = createMock(Map.class);
+        Definition definition = createMock(Definition.class);
+
+        expect(request.getContext("request")).andReturn(scope).anyTimes();
+        expect(scope.get(DEFAULT_DEFINITIONS_ATTRIBUTE_NAME)).andReturn(
+                definitions).anyTimes();
+        expect(definition.getName()).andReturn(null);
+        expect(definitions.containsKey("$anonymousMutableDefinition1"))
+                .andReturn(false);
+        definition.setName("$anonymousMutableDefinition1");
+        expect(definition.isExtending()).andReturn(true);
+        // trick to test resolve definition separately.
+        expect(definition.isExtending()).andReturn(true);
+        expect(definition.getExtends()).andReturn("parent");
+        expect(definitions.get("parent")).andReturn(null);
+        expect(wrapped.getDefinition("parent", request)).andReturn(null);
+        expect(definition.getName()).andReturn("$anonymousMutableDefinition1");
+
+        replay(wrapped, request, definitions, scope, definition);
+        try {
+            container.register(definition, request);
+        } finally {
+            verify(wrapped, request, definitions, scope, definition);
+        }
+    }
+
+    /**
+     * Test method for
+     * {@link CachingTilesContainer#register(Definition, Request)}
+     * .
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testRegisterCreateDefinitions() {
+        Request request = createMock(Request.class);
+        Map<String, Object> scope = createMock(Map.class);
+        Definition definition = createMock(Definition.class);
+
+        expect(request.getContext("request")).andReturn(scope).anyTimes();
+        expect(scope.get(DEFAULT_DEFINITIONS_ATTRIBUTE_NAME)).andReturn(
+                null);
+        expect(scope.put(eq(DEFAULT_DEFINITIONS_ATTRIBUTE_NAME), isA(HashMap.class))).andReturn(null);
+        expect(definition.getName()).andReturn(null);
+        definition.setName("$anonymousMutableDefinition1");
+        expect(definition.isExtending()).andReturn(true);
+        // trick to test resolve definition separately.
+        expect(definition.isExtending()).andReturn(false);
+        expect(definition.getName()).andReturn("$anonymousMutableDefinition1");
+
+        replay(wrapped, request, scope, definition);
+        container.register(definition, request);
+        verify(wrapped, request, scope, definition);
+    }
+
+    /**
+     * Test method for
+     * {@link org.apache.tiles.impl.mgmt.CachingTilesContainer#render(String, Request)}
+     * .
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testRender() {
+        Request request = createMock(Request.class);
+        Map<String, Definition> definitions = createMock(Map.class);
+        Map<String, Object> scope = createMock(Map.class);
+        Definition definition = createMock(Definition.class);
+
+        expect(request.getContext("request")).andReturn(scope);
+        expect(scope.get(DEFAULT_DEFINITIONS_ATTRIBUTE_NAME)).andReturn(
+                definitions);
+        expect(definitions.get("definition")).andReturn(definition);
+        container.render(definition, request);
+
+        replay(wrapped, request, definitions, scope, definition);
+        container.render("definition", request);
+        verify(wrapped, request, definitions, scope, definition);
+    }
+
+    /**
+     * Test method for
+     * {@link org.apache.tiles.impl.mgmt.CachingTilesContainer#render(String, Request)}
+     * .
+     */
+    @SuppressWarnings("unchecked")
+    @Test(expected = NoSuchDefinitionException.class)
+    public void testRenderFail() {
+        Request request = createMock(Request.class);
+        Map<String, Definition> definitions = createMock(Map.class);
+        Map<String, Object> scope = createMock(Map.class);
+
+        expect(request.getContext("request")).andReturn(scope);
+        expect(scope.get(DEFAULT_DEFINITIONS_ATTRIBUTE_NAME)).andReturn(
+                definitions);
+        expect(definitions.get("definition")).andReturn(null);
+        expect(wrapped.getDefinition("definition", request)).andReturn(null);
+
+        replay(wrapped, request, definitions, scope);
+        try {
+            container.render("definition", request);
+        } finally {
+            verify(wrapped, request, definitions, scope);
+        }
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/locale/impl/DefaultLocaleResolverTest.java b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/locale/impl/DefaultLocaleResolverTest.java
new file mode 100644
index 000000000..d7933ee2c
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/locale/impl/DefaultLocaleResolverTest.java
@@ -0,0 +1,59 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.locale.impl;
+
+import static org.easymock.classextension.EasyMock.*;
+import static org.junit.Assert.*;
+
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.tiles.request.Request;
+import org.junit.Test;
+
+/**
+ * Tests {@link DefaultLocaleResolver}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class DefaultLocaleResolverTest {
+
+    /**
+     * Test method for {@link DefaultLocaleResolver#resolveLocale(Request)}.
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testResolveLocale() {
+        Request request = createMock(Request.class);
+        Map<String, Object> sessionScope = createMock(Map.class);
+        Locale locale = Locale.ITALY;
+
+        expect(request.getContext("session")).andReturn(sessionScope);
+        expect(sessionScope.get(DefaultLocaleResolver.LOCALE_KEY)).andReturn(null);
+        expect(request.getRequestLocale()).andReturn(locale);
+
+        replay(request, sessionScope);
+        DefaultLocaleResolver resolver = new DefaultLocaleResolver();
+        assertSame(locale, resolver.resolveLocale(request));
+        verify(request, sessionScope);
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/preparer/factory/BasicPreparerFactoryTest.java b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/preparer/factory/BasicPreparerFactoryTest.java
new file mode 100644
index 000000000..e03cd858f
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/preparer/factory/BasicPreparerFactoryTest.java
@@ -0,0 +1,73 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.preparer.factory;
+
+import org.apache.tiles.AttributeContext;
+import org.apache.tiles.preparer.ViewPreparer;
+import org.apache.tiles.request.Request;
+
+import junit.framework.TestCase;
+
+/**
+ * Tests the basic preparer factory.
+ *
+ * @version $Rev$ $Date$
+ */
+public class BasicPreparerFactoryTest extends TestCase {
+
+    /**
+     * The preparer factory.
+     */
+    private BasicPreparerFactory factory;
+
+    /** {@inheritDoc} */
+    @Override
+    public void setUp() {
+        factory = new BasicPreparerFactory();
+    }
+
+    /**
+     * Tests getting a preparer.
+     */
+    public void testGetPreparer() {
+        String name = MockViewPreparer.class.getName();
+        ViewPreparer p = factory.getPreparer(name, null);
+        assertNotNull(p);
+        assertTrue(p instanceof MockViewPreparer);
+
+        name = "org.doesnotexist.Class";
+        p = factory.getPreparer(name, null);
+        assertNull(p);
+    }
+
+    /**
+     * Mock view preparer.
+     *
+     * @version $Rev$ $Date$
+     */
+    public static class MockViewPreparer implements ViewPreparer {
+
+        /** {@inheritDoc} */
+        public void execute(Request tilesContext,
+                            AttributeContext attributeContext) {
+        }
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/preparer/factory/NoSuchPreparerExceptionTest.java b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/preparer/factory/NoSuchPreparerExceptionTest.java
new file mode 100644
index 000000000..44825b948
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/preparer/factory/NoSuchPreparerExceptionTest.java
@@ -0,0 +1,77 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.preparer.factory;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+/**
+ * Tests {@link NoSuchPreparerException}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class NoSuchPreparerExceptionTest {
+
+    /**
+     * Test method for {@link NoSuchPreparerException#NoSuchPreparerException()}.
+     */
+    @Test
+    public void testNoSuchPreparerException() {
+        NoSuchPreparerException exception = new NoSuchPreparerException();
+        assertNull(exception.getMessage());
+        assertNull(exception.getCause());
+    }
+
+    /**
+     * Test method for {@link NoSuchPreparerException#NoSuchPreparerException(java.lang.String)}.
+     */
+    @Test
+    public void testNoSuchPreparerExceptionString() {
+        NoSuchPreparerException exception = new NoSuchPreparerException("my message");
+        assertEquals("my message", exception.getMessage());
+        assertNull(exception.getCause());
+    }
+
+    /**
+     * Test method for {@link NoSuchPreparerException#NoSuchPreparerException(java.lang.Throwable)}.
+     */
+    @Test
+    public void testNoSuchPreparerExceptionThrowable() {
+        Throwable cause = new Throwable();
+        NoSuchPreparerException exception = new NoSuchPreparerException(cause);
+        assertEquals(cause.toString(), exception.getMessage());
+        assertEquals(cause, exception.getCause());
+    }
+
+    /**
+     * Test method for {@link NoSuchPreparerException#NoSuchPreparerException(java.lang.String, java.lang.Throwable)}.
+     */
+    @Test
+    public void testNoSuchPreparerExceptionStringThrowable() {
+        Throwable cause = new Throwable();
+        NoSuchPreparerException exception = new NoSuchPreparerException("my message", cause);
+        assertEquals("my message", exception.getMessage());
+        assertEquals(cause, exception.getCause());
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/renderer/DefinitionRendererTest.java b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/renderer/DefinitionRendererTest.java
new file mode 100644
index 000000000..6bc11349a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/renderer/DefinitionRendererTest.java
@@ -0,0 +1,104 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.renderer;
+
+import static org.easymock.EasyMock.*;
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.request.Request;
+import org.apache.tiles.request.render.CannotRenderException;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests {@link DefinitionRenderer}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class DefinitionRendererTest {
+
+    /**
+     * The renderer.
+     */
+    private DefinitionRenderer renderer;
+
+    /**
+     * The container.
+     */
+    private TilesContainer container;
+
+    /** {@inheritDoc} */
+    @Before
+    public void setUp() {
+        container = createMock(TilesContainer.class);
+        renderer = new DefinitionRenderer(container);
+    }
+
+    /**
+     * Tests
+     * {@link DefinitionRenderer#render(String, Request)}.
+     *
+     * @throws IOException If something goes wrong during rendition.
+     */
+    @Test
+    public void testWrite() throws IOException {
+        Request requestContext = createMock(Request.class);
+        container.render("my.definition", requestContext);
+        replay(requestContext, container);
+        renderer.render("my.definition", requestContext);
+        verify(requestContext, container);
+    }
+
+    /**
+     * Tests
+     * {@link DefinitionRenderer#render(String, Request)}.
+     *
+     * @throws IOException If something goes wrong during rendition.
+     */
+    @Test(expected = CannotRenderException.class)
+    public void testRenderException() throws IOException {
+        Request requestContext = createMock(Request.class);
+        replay(requestContext, container);
+        try {
+            renderer.render(null, requestContext);
+        } finally {
+            verify(requestContext, container);
+        }
+    }
+
+    /**
+     * Tests
+     * {@link DefinitionRenderer#isRenderable(String, Request)}
+     * .
+     */
+    @Test
+    public void testIsRenderable() {
+        Request requestContext = createMock(Request.class);
+        expect(container.isValidDefinition("my.definition", requestContext)).andReturn(Boolean.TRUE);
+        replay(requestContext, container);
+        assertTrue(renderer.isRenderable("my.definition", requestContext));
+        assertFalse(renderer.isRenderable(null, requestContext));
+        verify(requestContext, container);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/startup/AbstractTilesInitializerTest.java b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/startup/AbstractTilesInitializerTest.java
new file mode 100644
index 000000000..361ff45ff
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/startup/AbstractTilesInitializerTest.java
@@ -0,0 +1,129 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.startup;
+
+import static org.easymock.classextension.EasyMock.*;
+import static org.junit.Assert.*;
+
+import java.util.Map;
+
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.access.TilesAccess;
+import org.apache.tiles.factory.AbstractTilesContainerFactory;
+import org.apache.tiles.request.ApplicationAccess;
+import org.apache.tiles.request.ApplicationContext;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests {@link AbstractTilesInitializer}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class AbstractTilesInitializerTest {
+
+    /**
+     * A mock Tiles container factory.
+     */
+    private AbstractTilesContainerFactory containerFactory;
+
+    /**
+     * The object to test.
+     */
+    private AbstractTilesInitializer initializer;
+
+    /**
+     * Sets up the test.
+     */
+    @Before
+    public void setUp() {
+        containerFactory = createMock(AbstractTilesContainerFactory.class);
+        initializer = new AbstractTilesInitializer() {
+
+            @Override
+            protected AbstractTilesContainerFactory createContainerFactory(
+                    ApplicationContext context) {
+                return containerFactory;
+            }
+        };
+    }
+
+    /**
+     * Test method for {@link AbstractTilesInitializer#initialize(ApplicationContext)}.
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testInitialize() {
+        ApplicationContext context = createMock(ApplicationContext.class);
+        TilesContainer container = createMock(TilesContainer.class);
+        Map<String, Object> scope = createMock(Map.class);
+
+        expect(containerFactory.createContainer(context)).andReturn(container);
+        expect(context.getApplicationScope()).andReturn(scope).anyTimes();
+        expect(scope.put(ApplicationAccess.APPLICATION_CONTEXT_ATTRIBUTE,
+                context)).andReturn(null);
+        expect(scope.put(TilesAccess.CONTAINER_ATTRIBUTE, container)).andReturn(null);
+        expect(scope.remove(TilesAccess.CONTAINER_ATTRIBUTE)).andReturn(container);
+
+        replay(containerFactory, context, container, scope);
+        initializer.initialize(context);
+        initializer.destroy();
+        verify(containerFactory, context, container, scope);
+    }
+
+    /**
+     * Test method for {@link AbstractTilesInitializer#createTilesApplicationContext(ApplicationContext)}.
+     */
+    @Test
+    public void testCreateTilesApplicationContext() {
+        ApplicationContext context = createMock(ApplicationContext.class);
+        replay(containerFactory, context);
+        assertEquals(context, initializer.createTilesApplicationContext(context));
+        verify(containerFactory, context);
+    }
+
+    /**
+     * Test method for {@link AbstractTilesInitializer#getContainerKey(ApplicationContext)}.
+     */
+    @Test
+    public void testGetContainerKey() {
+        ApplicationContext context = createMock(ApplicationContext.class);
+        replay(containerFactory, context);
+        assertNull(initializer.getContainerKey(context));
+        verify(containerFactory, context);
+    }
+
+    /**
+     * Test method for {@link AbstractTilesInitializer#createContainer(ApplicationContext)}.
+     */
+    @Test
+    public void testCreateContainer() {
+        ApplicationContext context = createMock(ApplicationContext.class);
+        TilesContainer container = createMock(TilesContainer.class);
+
+        expect(containerFactory.createContainer(context)).andReturn(container);
+
+        replay(containerFactory, context, container);
+        assertEquals(container, initializer.createContainer(context));
+        verify(containerFactory, context, container);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/startup/DefaultTilesInitializerTest.java b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/startup/DefaultTilesInitializerTest.java
new file mode 100644
index 000000000..73ea134cc
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/startup/DefaultTilesInitializerTest.java
@@ -0,0 +1,50 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.startup;
+
+import static org.junit.Assert.*;
+import static org.easymock.EasyMock.*;
+
+import org.apache.tiles.factory.BasicTilesContainerFactory;
+import org.apache.tiles.request.ApplicationContext;
+import org.junit.Test;
+
+/**
+ * Tests {@link DefaultTilesInitializer}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class DefaultTilesInitializerTest {
+
+    /**
+     * Test method for {@link DefaultTilesInitializer#createContainerFactory(ApplicationContext)}.
+     */
+    @Test
+    public void testCreateContainerFactory() {
+        ApplicationContext context = createMock(ApplicationContext.class);
+
+        replay(context);
+        DefaultTilesInitializer initializer = new DefaultTilesInitializer();
+        assertTrue(initializer.createContainerFactory(context) instanceof BasicTilesContainerFactory);
+        verify(context);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/util/CombinedBeanInfoTest.java b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/util/CombinedBeanInfoTest.java
new file mode 100644
index 000000000..59ea8792a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/util/CombinedBeanInfoTest.java
@@ -0,0 +1,106 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.util;
+
+import static org.junit.Assert.*;
+
+import java.beans.FeatureDescriptor;
+import java.beans.PropertyDescriptor;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.Request;
+import org.apache.tiles.request.reflect.ClassUtil;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests {@link CombinedBeanInfo}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class CombinedBeanInfoTest {
+
+    /**
+     * The bean info to test.
+     */
+    private CombinedBeanInfo beanInfo;
+
+    /**
+     * The property descriptors.
+     */
+    private List<FeatureDescriptor> descriptors;
+
+    /**
+     * The map of property descriptors for request.
+     */
+    private Map<String, PropertyDescriptor> requestMap;
+
+    /**
+     * The map of property descriptors for application.
+     */
+    private Map<String, PropertyDescriptor> applicationMap;
+
+    /**
+     * Sets up the test.
+     */
+    @Before
+    public void setUp() {
+        beanInfo = new CombinedBeanInfo(Request.class, ApplicationContext.class);
+        requestMap = new LinkedHashMap<String, PropertyDescriptor>();
+        ClassUtil.collectBeanInfo(Request.class, requestMap);
+        applicationMap = new LinkedHashMap<String, PropertyDescriptor>();
+        ClassUtil.collectBeanInfo(ApplicationContext.class, applicationMap);
+        descriptors = new ArrayList<FeatureDescriptor>();
+        descriptors.addAll(requestMap.values());
+        descriptors.addAll(applicationMap.values());
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.util.CombinedBeanInfo#getDescriptors()}.
+     */
+    @Test
+    public void testGetDescriptors() {
+        assertEquals(descriptors, beanInfo.getDescriptors());
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.util.CombinedBeanInfo#getMappedDescriptors(java.lang.Class)}.
+     */
+    @Test
+    public void testGetMappedDescriptors() {
+        assertEquals(requestMap, beanInfo.getMappedDescriptors(Request.class));
+        assertEquals(applicationMap, beanInfo.getMappedDescriptors(ApplicationContext.class));
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.util.CombinedBeanInfo#getProperties(java.lang.Class)}.
+     */
+    @Test
+    public void testGetProperties() {
+        assertEquals(requestMap.keySet(), beanInfo.getProperties(Request.class));
+        assertEquals(applicationMap.keySet(), beanInfo.getProperties(ApplicationContext.class));
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/util/RollingVectorEnumeration.java b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/util/RollingVectorEnumeration.java
new file mode 100644
index 000000000..e06b33b1e
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/java/org/apache/tiles/util/RollingVectorEnumeration.java
@@ -0,0 +1,76 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.util;
+
+import java.util.Enumeration;
+import java.util.Vector;
+
+/**
+ * It represents an vector-based enumeration when, when it has finished
+ * enumerating items, it starts from the beginning.
+ *
+ * @param <E> The type of the element of this enumeration.
+ * @version $Rev$ $Date$
+ */
+public class RollingVectorEnumeration<E> implements Enumeration<E> {
+
+    /**
+     * The vector.
+     */
+    private Vector<E> vector;
+
+    /**
+     * The elements.
+     */
+    private Enumeration<E> elements;
+
+    /**
+     * Constructor.
+     *
+     * @param vector The vector.
+     */
+    public RollingVectorEnumeration(Vector<E> vector) {
+        this.vector = vector;
+        elements = vector.elements();
+    }
+
+    /** {@inheritDoc} */
+    public boolean hasMoreElements() {
+        if (elements == null) {
+            elements = vector.elements();
+            return false;
+        }
+        return elements.hasMoreElements();
+    }
+
+    /** {@inheritDoc} */
+    public E nextElement() {
+        E retValue = elements.nextElement();
+
+        if (!elements.hasMoreElements()) {
+            elements = null;
+        }
+
+        return retValue;
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/defs-tiles-513.xml b/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/defs-tiles-513.xml
new file mode 100644
index 000000000..698d5d1e6
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/defs-tiles-513.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+ -->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 2.1//EN"
+       "http://tiles.apache.org/dtds/tiles-config_2_1.dtd">
+
+<!-- Definitions for Tiles documentation -->
+
+<tiles-definitions>
+  <!-- Authentication Layout -->
+  <definition name="test.anonymous.base" template="/layout.jsp">
+    <put-attribute name="header">
+      <definition template="/header.jsp" />
+    </put-attribute>
+    <put-attribute name="menu">
+      <definition template="/localnav.jsp" />
+    </put-attribute>
+    <put-attribute name="footer">
+      <definition template="/footer.jsp" />
+    </put-attribute>
+  </definition>
+
+  <!-- index page -->
+  <definition name="test.anonymous" extends="test.anonymous.base">
+    <put-attribute name="title" value="page.title.security.login" />
+    <put-attribute name="body" value="/body.jsp" />
+  </definition>
+</tiles-definitions>
diff --git a/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/defs-wildcard.xml b/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/defs-wildcard.xml
new file mode 100644
index 000000000..6590b7e38
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/defs-wildcard.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"
+       "http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
+
+<!-- Definitions for Tiles documentation   -->
+
+<tiles-definitions>
+  <definition name="test.def3" template="/test.jsp">
+    <put-attribute name="title"  value="Tiles Library Documentation" />
+    <put-attribute name="header" value="/common/header.jsp" />
+    <put-attribute name="menu"   value="doc.menu.main" />
+    <put-attribute name="footer" value="/common/footer.jsp" />
+    <put-attribute name="body"   value="doc.portal.body" />
+  </definition>
+  <definition name="test.def*.sub*" template="/test{1}.jsp">
+      <put-attribute name="country" value="default"/>
+      <put-attribute name="title"  value="Tiles Library Documentation" />
+      <put-attribute name="header" value="/common/header{2}.jsp" />
+      <put-attribute name="menu"   value="doc.menu.main" />
+      <put-attribute name="footer" value="/common/footer.jsp" />
+      <put-attribute name="body"   value="doc.portal.body" />
+  </definition>
+
+  <definition name="test.def*.noAttribute" template="/test{1}.jsp" />
+
+  <!-- Never used on purpose, if there is the TILES-416 the test will fail -->
+  <definition name="test.def*" template="/test{1}.jsp">
+      <put-attribute name="country" value="default"/>
+      <put-attribute name="title"  value="Tiles Library Documentation" />
+      <put-attribute name="header" value="/common/header-sub.jsp" />
+      <put-attribute name="menu"   value="doc.menu.main" />
+      <put-attribute name="footer" value="/common/footer.jsp" />
+      <put-attribute name="body"   value="doc.portal.body" />
+  </definition>
+
+  <definition name="test.extended.def*.sub*" extends="test.def{1}.sub{2}">
+      <put-attribute name="title"  value="Overridden Title" />
+  </definition>
+
+</tiles-definitions>
diff --git a/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/defs1.xml b/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/defs1.xml
new file mode 100644
index 000000000..6cde50d03
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/defs1.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"
+       "http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
+
+<!-- Definitions for Tiles documentation   -->
+
+<tiles-definitions>
+
+  <!-- =======================================================  -->
+  <!-- Master definition  									-->
+  <!-- =======================================================  -->
+
+  <!-- This definition will remain the same for all locales -->
+  <definition name="test.common" template="/test.jsp">
+      <put-attribute name="country" value="none"/>
+    <put-attribute name="title"  value="Common Definition" />
+    <put-attribute name="header" value="/common/header.jsp" />
+    <put-attribute name="menu"   value="doc.menu.main" />
+    <put-attribute name="footer" value="/common/footer.jsp" />
+    <put-attribute name="body"   value="doc.portal.body" />
+  </definition>
+
+  <!-- Doc index page description  -->
+  <definition name="test.def1" template="/test.jsp">
+          <put-attribute name="country" value="default"/>
+    <put-attribute name="title"  value="Tiles Library Documentation" />
+    <put-attribute name="header" value="/common/header.jsp" />
+    <put-attribute name="menu"   value="doc.menu.main" />
+    <put-attribute name="footer" value="/common/footer.jsp" />
+    <put-attribute name="body"   value="doc.portal.body" />
+  </definition>
+
+  <!-- This definition will be extended -->
+  <definition name="test.def.toextend" template="/test.jsp">
+    <put-attribute name="country" value="default"/>
+    <put-attribute name="title"  value="Definition to be extended" />
+    <put-attribute name="header" value="/common/header.jsp" />
+    <put-attribute name="menu"   value="doc.menu.main" />
+    <put-attribute name="footer" value="/common/footer.jsp" />
+    <put-attribute name="body"   value="doc.portal.body" />
+  </definition>
+
+  <!-- This definition will be overridden -->
+  <definition name="test.def.overridden" template="/test.jsp">
+    <put-attribute name="country" value="default"/>
+    <put-attribute name="title"  value="Definition to be overridden" />
+    <put-attribute name="header" value="/common/header.jsp" />
+    <put-attribute name="menu"   value="doc.menu.main" />
+    <put-attribute name="footer" value="/common/footer.jsp" />
+    <put-attribute name="body"   value="doc.portal.body" />
+  </definition>
+
+</tiles-definitions>
diff --git a/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/defs1_en_US.xml b/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/defs1_en_US.xml
new file mode 100644
index 000000000..9bb423d0e
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/defs1_en_US.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"
+       "http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
+
+<!-- Definitions for Tiles documentation   -->
+
+<tiles-definitions>
+
+  <!-- =======================================================  -->
+  <!-- Master definition  									-->
+  <!-- =======================================================  -->
+
+  <!-- Doc index page description  -->
+  <definition name="test.def1" template="/test.jsp">
+          <put-attribute name="country" value="US"/>
+    <put-attribute name="title"  value="Tiles Library Documentation" />
+    <put-attribute name="header" value="/common/header.jsp" />
+    <put-attribute name="menu"   value="doc.menu.main" />
+    <put-attribute name="footer" value="/common/footer.jsp" />
+    <put-attribute name="body"   value="doc.portal.body" />
+  </definition>
+
+</tiles-definitions>
diff --git a/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/defs1_fr.xml b/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/defs1_fr.xml
new file mode 100644
index 000000000..798a76e77
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/defs1_fr.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"
+       "http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
+
+<!-- Definitions for Tiles documentation   -->
+
+<tiles-definitions>
+
+  <!-- =======================================================  -->
+  <!-- Master definition  									-->
+  <!-- =======================================================  -->
+
+  <!-- Doc index page description  -->
+  <definition name="test.def1" template="/test.jsp">
+          <put-attribute name="country" value="France"/>
+    <put-attribute name="title"  value="Tiles Library Documentation" />
+    <put-attribute name="header" value="/common/header.jsp" />
+    <put-attribute name="menu"   value="doc.menu.main" />
+    <put-attribute name="footer" value="/common/footer.jsp" />
+    <put-attribute name="body"   value="doc.portal.body" />
+  </definition>
+
+  <definition name="test.common.french" template="/test.jsp">
+          <put-attribute name="country" value="France"/>
+    <put-attribute name="title"  value="Common Definition for French" />
+    <put-attribute name="header" value="/common/header.jsp" />
+    <put-attribute name="menu"   value="doc.menu.main" />
+    <put-attribute name="footer" value="/common/footer.jsp" />
+    <put-attribute name="body"   value="doc.portal.body" />
+  </definition>
+
+  <definition name="test.def.overridden" extends="test.def.toextend">
+    <put-attribute name="country" value="France"/>
+  </definition>
+
+</tiles-definitions>
diff --git a/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/defs1_fr_CA.xml b/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/defs1_fr_CA.xml
new file mode 100644
index 000000000..1a74e50b2
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/defs1_fr_CA.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"
+       "http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
+
+<!-- Definitions for Tiles documentation   -->
+
+<tiles-definitions>
+
+  <!-- =======================================================  -->
+  <!-- Master definition  									-->
+  <!-- =======================================================  -->
+
+  <!-- Doc index page description  -->
+  <definition name="test.def1" template="/test.jsp">
+          <put-attribute name="country" value="Canada"/>
+    <put-attribute name="title"  value="Tiles Library Documentation" />
+    <put-attribute name="header" value="/common/header.jsp" />
+    <put-attribute name="menu"   value="doc.menu.main" />
+    <put-attribute name="footer" value="/common/footer.jsp" />
+    <put-attribute name="body"   value="doc.portal.body" />
+  </definition>
+
+</tiles-definitions>
diff --git a/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/defs2.xml b/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/defs2.xml
new file mode 100644
index 000000000..b16912b57
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/defs2.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"
+       "http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
+
+<!-- Definitions for Tiles documentation   -->
+
+<tiles-definitions>
+
+  <!-- =======================================================  -->
+  <!-- Master definition  									-->
+  <!-- =======================================================  -->
+
+  <!-- Doc index page description  -->
+  <definition name="test.def2" template="/test.jsp">
+    <put-attribute name="title"  value="Tiles Library Documentation" />
+    <put-attribute name="header" value="/common/header.jsp" />
+    <put-attribute name="menu"   value="doc.menu.main" />
+    <put-attribute name="footer" value="/common/footer.jsp" />
+    <put-attribute name="body"   value="doc.portal.body" />
+  </definition>
+
+</tiles-definitions>
diff --git a/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/defs3.xml b/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/defs3.xml
new file mode 100644
index 000000000..9a964a553
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/defs3.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"
+       "http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
+
+<!-- Definitions for Tiles documentation   -->
+
+<tiles-definitions>
+
+  <!-- =======================================================  -->
+  <!-- Master definition  									-->
+  <!-- =======================================================  -->
+
+  <!-- Doc index page description  -->
+  <definition name="test.def3" template="/test.jsp">
+    <put-attribute name="title"  value="Tiles Library Documentation" />
+    <put-attribute name="header" value="/common/header.jsp" />
+    <put-attribute name="menu"   value="doc.menu.main" />
+    <put-attribute name="footer" value="/common/footer.jsp" />
+    <put-attribute name="body"   value="doc.portal.body" />
+  </definition>
+
+</tiles-definitions>
diff --git a/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/defs_regression_TILES-352.xml b/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/defs_regression_TILES-352.xml
new file mode 100644
index 000000000..2f17015e0
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/defs_regression_TILES-352.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+ <!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+ -->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"
+       "http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
+
+ <!-- Definitions to check regression from TILES-252    -->
+
+<tiles-definitions>
+ <definition name="root">
+  <put-attribute name="body">
+   <definition template="/my/template.jsp">
+    <put-list-attribute name="list">
+     <add-attribute value="This is a value" type="string" />
+    </put-list-attribute>
+   </definition>
+  </put-attribute>
+ </definition>
+
+</tiles-definitions>
diff --git a/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/invalid-defs.xml b/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/invalid-defs.xml
new file mode 100644
index 000000000..28d05b00a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/invalid-defs.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"
+       "http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
+
+<!-- Definitions for Tiles documentation   -->
+
+<tiles-definitions>
+
+  <!-- =======================================================  -->
+  <!-- Master definition  									-->
+  <!-- =======================================================  -->
+
+  <!-- Dorked up XML tag.  -->
+  <definitionasdfad name="doc.mainLayout" template="/layout/classicLayout.jsp">
+    <put-attribute name="title"  value="Tiles Library Documentation" />
+    <put-attribute name="header" value="/common/header.jsp" />
+    <put-attribute name="menu"   value="doc.menu.main" />
+    <put-attribute name="footer" value="/common/footer.jsp" />
+    <put-attribute name="body"   value="doc.portal.body" />
+  </definitionasdfad>
+
+</tiles-definitions>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/malformed-defs.xml b/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/malformed-defs.xml
new file mode 100644
index 000000000..9175bd913
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/malformed-defs.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"
+       "http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
+
+<!-- Definitions for Tiles documentation   -->
+
+<tiles-definitions>
+
+  <!-- =======================================================  -->
+  <!-- Master definition  									-->
+  <!-- =======================================================  -->
+
+  <!-- Doc index page description  -->
+  <definition name="doc.mainLayout" template="/layout/classicLayout.jsp">
+    <put-attribute name="title"  value="Tiles Library Documentation" />
+    <put-attribute name="header" value="/common/header.jsp" />
+    <put-attribute name="menu"   value="doc.menu.main" />
+    <put-attribute name="footer" value="/common/footer.jsp" />
+    <put-attribute name="body"   value="doc.portal.body" />
+  </definition>
diff --git a/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/temp-defs.xml b/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/temp-defs.xml
new file mode 100644
index 000000000..5d5e6d4bc
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/temp-defs.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"
+       "http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
+
+<!-- Definitions for Tiles documentation   -->
+
+<tiles-definitions>
+
+  <!-- =======================================================  -->
+  <!-- Master definition  									-->
+  <!-- =======================================================  -->
+
+  <!-- Doc index page description  -->
+  <definition name="test.def1" template="/test.jsp">
+          <put-attribute name="country" value="default"/>
+    <put-attribute name="title"  value="Tiles Library Documentation" />
+    <put-attribute name="header" value="/common/header.jsp" />
+    <put-attribute name="menu"   value="doc.menu.main" />
+    <put-attribute name="footer" value="/common/footer.jsp" />
+    <put-attribute name="body"   value="doc.portal.body" />
+  </definition>
+
+</tiles-definitions>
diff --git a/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/tiles-defs-2.1.xml b/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/tiles-defs-2.1.xml
new file mode 100644
index 000000000..3a602e33b
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/tiles-defs-2.1.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"
+       "http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
+
+<!-- Definitions for Tiles documentation   -->
+
+<tiles-definitions>
+  <definition name="doc.cascaded.test" template="/layout/classicLayout.jsp">
+    <put-attribute name="title" value="Test title" cascade="false" />
+    <put-attribute name="title2" value="Test title two" cascade="true" />
+    <put-list-attribute name="items1" cascade="false">
+        <add-attribute value="value1" type="string" />
+    </put-list-attribute>
+    <put-list-attribute name="items2" cascade="true">
+        <add-attribute value="value2" type="string" />
+    </put-list-attribute>
+  </definition>
+
+  <definition name="test.nesting.definitions" template="/layout.jsp">
+      <put-attribute name="body">
+          <definition template="/layout.jsp">
+              <put-attribute name="title"  value="This is a nested definition."/>
+          </definition>
+      </put-attribute>
+  </definition>
+
+  <definition name="test.nesting.list.definitions" template="/layout.jsp">
+      <put-list-attribute name="list">
+          <add-attribute>
+              <definition template="/layout.jsp">
+                  <put-attribute name="title"  value="This is a nested definition."/>
+              </definition>
+          </add-attribute>
+      </put-list-attribute>
+  </definition>
+
+  <definition name="test.inherit.list.base" template="/layout.jsp">
+      <put-list-attribute name="list">
+          <add-attribute value="first" />
+      </put-list-attribute>
+  </definition>
+
+  <definition name="test.inherit.list" extends="test.inherit.list.base">
+      <put-list-attribute name="list" inherit="true">
+          <add-attribute value="second" />
+      </put-list-attribute>
+  </definition>
+
+  <definition name="test.noinherit.list" extends="test.inherit.list.base">
+      <put-list-attribute name="list">
+          <add-attribute value="second" />
+      </put-list-attribute>
+  </definition>
+
+  <definition name="test.new.attributes" templateExpression="${my.expression}"
+          templateType="mytype" >
+      <put-attribute name="body" expression="${my.attribute.expression}" />
+  </definition>
+
+  <definition name="test.inherit.othertype.base" template="/layout.ftl" templateType="freemarker">
+      <put-attribute name="body" value="/jsp/body.jsp" />
+  </definition>
+
+  <definition name="test.inherit.othertype" extends="test.inherit.othertype.base">
+  </definition>
+</tiles-definitions>
diff --git a/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/tiles-defs-2.1_it.xml b/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/tiles-defs-2.1_it.xml
new file mode 100644
index 000000000..af9a227af
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/tiles-defs-2.1_it.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"
+       "http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
+
+<!-- Definitions for Tiles documentation   -->
+
+<tiles-definitions>
+  <definition name="test.dummy" template="/dummy_layout.jsp">
+      <put-attribute name="body" expression="/dummy_body.jsp" />
+  </definition>
+</tiles-definitions>
diff --git a/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/tiles-defs.xml b/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/tiles-defs.xml
new file mode 100644
index 000000000..daa42a58e
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/config/tiles-defs.xml
@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"
+       "http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
+
+<!-- Definitions for Tiles documentation   -->
+
+<tiles-definitions>
+
+  <!-- =======================================================  -->
+  <!-- Master definition  									-->
+  <!-- =======================================================  -->
+
+  <!-- Doc index page description  -->
+  <definition name="doc.mainLayout" template="/layout/classicLayout.jsp">
+    <put-attribute name="title"  value="Tiles Library Documentation" />
+    <put-attribute name="header" value="/common/header.jsp" />
+    <put-attribute name="menu"   value="doc.menu.main" />
+    <put-attribute name="footer" value="/common/footer.jsp" />
+    <put-attribute name="body"   value="doc.portal.body" />
+      <put-attribute name="bean"   value="This is an object" type="object" />
+  </definition>
+
+  <!-- =======================================================  -->
+  <!-- Main page body definitions  									-->
+  <!-- =======================================================  -->
+
+  <definition name="doc.portal.body" template="/layout/columnsLayout.jsp">
+    <put-attribute name="numCols" value="2" />
+    <put-list-attribute name="list0" >
+      <add-attribute value="/doc/portal/welcome.jsp" />
+      <add-attribute value="/doc/portal/features.jsp" />
+      <!--<add-attribute value="/doc/portal/todo.jsp" /> -->
+      <add-attribute value="/doc/portal/documentation.jsp" />
+    </put-list-attribute>
+    <put-list-attribute name="list1" >
+      <add-attribute value="/doc/portal/news.jsp" />
+      <add-attribute value="/doc/portal/download.jsp" />
+      <add-attribute value="/doc/portal/tilesCompsTemplates.jsp" />
+      <add-attribute value="/doc/portal/strutsIntegration.jsp" />
+      <add-attribute value="/doc/portal/comments.jsp" />
+      <add-attribute value="/doc/portal/revisions.jsp" />
+    </put-list-attribute>
+  </definition>
+
+  <!-- =======================================================  -->
+  <!-- Menus definitions  									-->
+  <!-- =======================================================  -->
+
+  <!-- Menu bar definition -->
+<definition name="doc.menu.main" template="/layout/vboxLayout.jsp" >
+  <put-list-attribute name="componentsList" >
+    <add-attribute value="doc.menu.links" />
+    <add-attribute value="doc.menu.taglib.references" />
+    <add-attribute value="doc.menu.printer.friendly" />
+    <add-attribute value="doc.menu.old.documents" />
+  </put-list-attribute>
+</definition>
+
+  <!-- Documentation menu definition v1.1-->
+<definition name="doc.menu.links" template="/layouts/menu.jsp" >
+  <put-attribute name="title" value="Documentation" />
+    <put-list-attribute name="items" >
+      <item value="Home"           link="/index.jsp"  />
+      <item value="Live Examples (new)" link="/examples/index.jsp"  />
+      <!--
+    <item> <value>Commented Examples</value>
+        <link>/examples/index.jsp</link>
+      <classtype>org.apache.tiles.beans.SimpleMenuItem</classtype>
+    </item>
+    -->
+      <item value="Quick overview" link="/doc/quickOverview.jsp"  />
+      <!--
+      <item value="Tutorial"       link="/doc/tutorial.jsp"  />
+      -->
+      <item value="Tutorial Live Examples" link="/tutorial/index.jsp" />
+      <item value="Download"       link="/doc/download.jsp" />
+      <item value="Installation"   link="/doc/installation.jsp" />
+      <item value="User Guide"	   link="/doc/userGuide.jsp" />
+      <item value="Javadoc"        link="/api/index.html" />
+      <item value="Struts Home"    link="http://www.apache.org"   icon="/images/struts-power.gif"
+      classtype="org.apache.tiles.beans.SimpleMenuItem" />
+    </put-list-attribute>
+</definition>
+
+  <!-- Printer friendly menu definition -->
+<definition name="doc.menu.printer.friendly" template="/layouts/menu.jsp" >
+  <put-attribute name="title" value="Printer Versions" />
+  <put-list-attribute name="items" >
+    <item value="Quick Overview"     link="/test/testAll.jsp" />
+    <item value="Tutorial"           link="/doc/tutorialBody.html" />
+    <item value="User Guide"         link="/doc/userGuideBody.html" />
+    <item value="Overview (old)"  	 link="/doc/overviewBody.html" />
+  </put-list-attribute>
+</definition>
+
+  <!-- Taglib menu definition -->
+<definition name="doc.menu.taglib.references" template="/layouts/menu.jsp" >
+  <put-attribute name="title" value="Tag Library Reference" />
+    <put-list-attribute name="items" >
+      <item value="Tiles Tags"     link="/doc/tilesTags.jsp" />
+      <!-- <item value="Extension Tags (old)"   link="/doc/extensionsTags.jsp" /> -->
+    </put-list-attribute>
+</definition>
+
+  <!-- Oldies menu definition -->
+<definition name="doc.menu.old.documents" template="/layouts/menu.jsp" >
+  <put-attribute name="title" value="Old Documents" />
+  <put-list-attribute name="items" >
+    <item value="Overview (old)"     link="/doc/overview.jsp" />
+  </put-list-attribute>
+</definition>
+
+<definition name="doc.role.test" template="/layout/classicLayout.jsp">
+  <put-attribute name="title" value="Test title" role="myrole" />
+</definition>
+
+<definition name="doc.listattribute.test" template="/layout/classicLayout.jsp">
+  <put-list-attribute name="items" />
+</definition>
+
+</tiles-definitions>
diff --git a/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/factory/test-defs-key-one.xml b/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/factory/test-defs-key-one.xml
new file mode 100644
index 000000000..1eff6b443
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/factory/test-defs-key-one.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
+       "http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
+
+<tiles-definitions>
+  <definition name="test.def.one" template="/test.jsp">
+          <put-attribute name="country" value="default"/>
+    <put-attribute name="title"  value="Tiles Library Documentation" />
+    <put-attribute name="header" value="/common/header.jsp" />
+    <put-attribute name="menu"   value="doc.menu.main" />
+    <put-attribute name="footer" value="/common/footer.jsp" />
+    <put-attribute name="body"   value="doc.portal.body" />
+  </definition>
+
+</tiles-definitions>
diff --git a/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/factory/test-defs-key-two.xml b/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/factory/test-defs-key-two.xml
new file mode 100644
index 000000000..7c2067555
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/factory/test-defs-key-two.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
+       "http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
+
+<tiles-definitions>
+  <definition name="test.def.two" template="/test.jsp">
+          <put-attribute name="country" value="default"/>
+    <put-attribute name="title"  value="Tiles Library Documentation" />
+    <put-attribute name="header" value="/common/header.jsp" />
+    <put-attribute name="menu"   value="doc.menu.main" />
+    <put-attribute name="footer" value="/common/footer.jsp" />
+    <put-attribute name="body"   value="doc.portal.body" />
+  </definition>
+
+</tiles-definitions>
diff --git a/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/factory/test-defs.xml b/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/factory/test-defs.xml
new file mode 100644
index 000000000..5e7cd1018
--- /dev/null
+++ b/Java-base/tiles/src/tiles-core/src/test/resources/org/apache/tiles/factory/test-defs.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
+       "http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
+
+<tiles-definitions>
+  <definition name="test.def1" template="/test.jsp">
+          <put-attribute name="country" value="default"/>
+    <put-attribute name="title"  value="Tiles Library Documentation" />
+    <put-attribute name="header" value="/common/header.jsp" />
+    <put-attribute name="menu"   value="doc.menu.main" />
+    <put-attribute name="footer" value="/common/footer.jsp" />
+    <put-attribute name="body"   value="doc.portal.body" />
+  </definition>
+
+</tiles-definitions>
diff --git a/Java-base/tiles/src/tiles-el/pom.xml b/Java-base/tiles/src/tiles-el/pom.xml
new file mode 100644
index 000000000..ed99907f3
--- /dev/null
+++ b/Java-base/tiles/src/tiles-el/pom.xml
@@ -0,0 +1,148 @@
+<?xml version="1.0"?>
+  <!--
+    /* * $Id$ * *
+    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. */
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+  <parent>
+    <groupId>org.apache.tiles</groupId>
+    <artifactId>tiles-parent</artifactId>
+    <version>3.1-SNAPSHOT</version>
+  </parent>
+
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>tiles-el</artifactId>
+  <packaging>jar</packaging>
+  <name>Tiles - EL support</name>
+  <description>Tiles EL (Expression Language) support: Classes and tag libraries to use EL as an expression language in attribute expressions.	</description>
+
+  <properties>
+    <tiles.osgi.symbolicName>org.apache.tiles.el</tiles.osgi.symbolicName>
+  </properties>
+
+  <build>
+    <resources>
+      <resource>
+        <directory>src/main/resources</directory>
+        <excludes>
+          <exclude>LICENSE.txt</exclude>
+          <exclude>NOTICE.txt</exclude>
+        </excludes>
+      </resource>
+      <resource>
+        <directory>src/main/resources</directory>
+        <includes>
+          <include>LICENSE.txt</include>
+          <include>NOTICE.txt</include>
+        </includes>
+        <targetPath>META-INF</targetPath>
+      </resource>
+    </resources>
+
+    <plugins>
+      <plugin>
+        <artifactId>maven-jar-plugin</artifactId>
+        <configuration>
+          <archive>
+            <manifest>
+            </manifest>
+          </archive>
+        </configuration>
+      </plugin>
+      <plugin> 
+        <groupId>org.apache.felix</groupId> 
+        <artifactId>maven-bundle-plugin</artifactId> 
+        <configuration> 
+          <instructions> 
+            <Import-Package> 
+              org.apache.el; resolution:=optional, 
+              * 
+            </Import-Package> 
+          </instructions> 
+        </configuration> 
+      </plugin>
+    </plugins>
+
+  </build>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.tiles</groupId>
+      <artifactId>tiles-core</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>jcl-over-slf4j</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-jdk14</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.easymock</groupId>
+      <artifactId>easymock</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.easymock</groupId>
+      <artifactId>easymockclassextension</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>javax.el</groupId>
+      <artifactId>el-api</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>javax.servlet</groupId>
+      <artifactId>servlet-api</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>javax.servlet.jsp</groupId>
+      <artifactId>jsp-api</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tomcat</groupId>
+      <artifactId>jasper-el</artifactId>
+      <version>6.0.20</version>
+      <scope>test</scope>
+      <exclusions>
+        <exclusion>
+          <groupId>org.apache.tomcat</groupId>
+          <artifactId>el-api</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+  </dependencies>
+
+</project>
diff --git a/Java-base/tiles/src/tiles-el/src/main/java/org/apache/tiles/el/ELAttributeEvaluator.java b/Java-base/tiles/src/tiles-el/src/main/java/org/apache/tiles/el/ELAttributeEvaluator.java
new file mode 100644
index 000000000..0e6b068d4
--- /dev/null
+++ b/Java-base/tiles/src/tiles-el/src/main/java/org/apache/tiles/el/ELAttributeEvaluator.java
@@ -0,0 +1,104 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.el;
+
+import javax.el.ELResolver;
+import javax.el.ExpressionFactory;
+import javax.el.ValueExpression;
+
+import org.apache.tiles.evaluator.AbstractAttributeEvaluator;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.Request;
+
+/**
+ * Evaluates string expression with typical EL syntax.<br>
+ * You can use normal EL syntax, knowing that the root objects are
+ * {@link Request}, {@link ApplicationContext} and beans
+ * contained in request, session and application scope.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.1
+ */
+public class ELAttributeEvaluator extends AbstractAttributeEvaluator {
+
+    /**
+     * Initialization parameter to decide the implementation of
+     * {@link ExpressionFactoryFactory}.
+     *
+     * @since 2.2.1
+     */
+    public static final String EXPRESSION_FACTORY_FACTORY_INIT_PARAM =
+        "org.apache.tiles.evaluator.el.ExpressionFactoryFactory";
+
+    /**
+     * The EL expression factory.
+     *
+     * @since 2.2.1
+     */
+    protected ExpressionFactory expressionFactory;
+
+    /**
+     * The EL resolver to use.
+     *
+     * @since 2.2.1
+     */
+    protected ELResolver resolver;
+
+    /**
+     * Constructor.
+     *
+     * @since 2.2.1
+     */
+    public ELAttributeEvaluator() {
+    }
+
+    /**
+     * Sets the expression factory to use.
+     *
+     * @param expressionFactory The expression factory.
+     * @since 2.2.1
+     */
+    public void setExpressionFactory(ExpressionFactory expressionFactory) {
+        this.expressionFactory = expressionFactory;
+    }
+
+    /**
+     * Sets the EL resolver to use.
+     *
+     * @param resolver The EL resolver.
+     * @since 2.2.1
+     */
+    public void setResolver(ELResolver resolver) {
+        this.resolver = resolver;
+    }
+
+    /** {@inheritDoc} */
+    public Object evaluate(String expression, Request request) {
+        ELContextImpl context = new ELContextImpl(resolver);
+        context.putContext(Request.class, request);
+        context.putContext(ApplicationContext.class,
+                request.getApplicationContext());
+        ValueExpression valueExpression = expressionFactory
+                .createValueExpression(context, expression, Object.class);
+
+        return valueExpression.getValue(context);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-el/src/main/java/org/apache/tiles/el/ELContextImpl.java b/Java-base/tiles/src/tiles-el/src/main/java/org/apache/tiles/el/ELContextImpl.java
new file mode 100644
index 000000000..2c5156903
--- /dev/null
+++ b/Java-base/tiles/src/tiles-el/src/main/java/org/apache/tiles/el/ELContextImpl.java
@@ -0,0 +1,147 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.el;
+
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.el.ELContext;
+import javax.el.ELResolver;
+import javax.el.FunctionMapper;
+import javax.el.ValueExpression;
+import javax.el.VariableMapper;
+
+/**
+ * Implementation of ELContext.<br>
+ * Copied from Apache Tomcat 6.0.16 source code.
+ *
+ * @since 2.2.1
+ */
+public class ELContextImpl extends ELContext {
+
+    /**
+     * A null function mapper.
+     */
+    private static final FunctionMapper NULL_FUNCTION_MAPPER = new FunctionMapper() {
+        @Override
+        public Method resolveFunction(String prefix, String localName) {
+            return null;
+        }
+    };
+
+    /**
+     * Default implementation for the variable mapper.
+     */
+    private static final class VariableMapperImpl extends VariableMapper {
+
+        /**
+         * The mapped variables.
+         */
+        private Map<String, ValueExpression> vars;
+
+        /** {@inheritDoc} */
+        @Override
+        public ValueExpression resolveVariable(String variable) {
+            if (vars == null) {
+                return null;
+            }
+            return vars.get(variable);
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public ValueExpression setVariable(String variable,
+                ValueExpression expression) {
+            if (vars == null) {
+                vars = new HashMap<String, ValueExpression>();
+            }
+            return vars.put(variable, expression);
+        }
+
+    }
+
+    /**
+     * The EL resolver to use.
+     */
+    private final ELResolver resolver;
+
+    /**
+     * The function mapper to use.
+     */
+    private FunctionMapper functionMapper = NULL_FUNCTION_MAPPER;
+
+    /**
+     * The variable mapper to use.
+     */
+    private VariableMapper variableMapper;
+
+    /**
+     * Constructor.
+     *
+     * @param resolver The resolver to use.
+     */
+    public ELContextImpl(ELResolver resolver) {
+        this.resolver = resolver;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public ELResolver getELResolver() {
+        return this.resolver;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public FunctionMapper getFunctionMapper() {
+        return this.functionMapper;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public VariableMapper getVariableMapper() {
+        if (this.variableMapper == null) {
+            this.variableMapper = new VariableMapperImpl();
+        }
+        return this.variableMapper;
+    }
+
+    /**
+     * Sets the function mapper to use.
+     *
+     * @param functionMapper The function mapper.
+     * @since 2.2.1
+     */
+    public void setFunctionMapper(FunctionMapper functionMapper) {
+        this.functionMapper = functionMapper;
+    }
+
+    /**
+     * Sets the variable mapper to use.
+     *
+     * @param variableMapper The variable mapper.
+     * @since 2.2.1
+     */
+    public void setVariableMapper(VariableMapper variableMapper) {
+        this.variableMapper = variableMapper;
+    }
+}
diff --git a/Java-base/tiles/src/tiles-el/src/main/java/org/apache/tiles/el/ExpressionFactoryFactory.java b/Java-base/tiles/src/tiles-el/src/main/java/org/apache/tiles/el/ExpressionFactoryFactory.java
new file mode 100644
index 000000000..ce600ad4a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-el/src/main/java/org/apache/tiles/el/ExpressionFactoryFactory.java
@@ -0,0 +1,41 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.el;
+
+import javax.el.ExpressionFactory;
+
+/**
+ * Interface to define a factory of {@link ExpressionFactory}.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.1
+ */
+public interface ExpressionFactoryFactory {
+
+    /**
+     * Returns the expression factory to use.
+     *
+     * @return The expression factory.
+     * @since 2.2.1
+     */
+    ExpressionFactory getExpressionFactory();
+}
diff --git a/Java-base/tiles/src/tiles-el/src/main/java/org/apache/tiles/el/JspExpressionFactoryFactory.java b/Java-base/tiles/src/tiles-el/src/main/java/org/apache/tiles/el/JspExpressionFactoryFactory.java
new file mode 100644
index 000000000..b663a3c21
--- /dev/null
+++ b/Java-base/tiles/src/tiles-el/src/main/java/org/apache/tiles/el/JspExpressionFactoryFactory.java
@@ -0,0 +1,64 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.el;
+
+import javax.el.ExpressionFactory;
+import javax.servlet.ServletContext;
+import javax.servlet.jsp.JspFactory;
+
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.ApplicationContextAware;
+
+/**
+ * Uses the JSP 2.1 {@link ExpressionFactory} to be used in Tiles.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.1
+ */
+public class JspExpressionFactoryFactory implements ExpressionFactoryFactory,
+        ApplicationContextAware {
+
+    /**
+     * The servlet context.
+     *
+     * @since 2.2.1
+     */
+    protected ServletContext servletContext;
+
+    /** {@inheritDoc} */
+    public void setApplicationContext(ApplicationContext applicationContext) {
+        Object context = applicationContext.getContext();
+        if (context instanceof ServletContext) {
+            this.servletContext = (ServletContext) context;
+        } else {
+            throw new IllegalArgumentException(
+                    "The application context does not hold an instance of "
+                    + "ServletContext, consider using JuelExpressionFactoryFactory");
+        }
+    }
+
+    /** {@inheritDoc} */
+    public ExpressionFactory getExpressionFactory() {
+        return JspFactory.getDefaultFactory().getJspApplicationContext(
+                servletContext).getExpressionFactory();
+    }
+}
diff --git a/Java-base/tiles/src/tiles-el/src/main/java/org/apache/tiles/el/ScopeELResolver.java b/Java-base/tiles/src/tiles-el/src/main/java/org/apache/tiles/el/ScopeELResolver.java
new file mode 100644
index 000000000..578cd97be
--- /dev/null
+++ b/Java-base/tiles/src/tiles-el/src/main/java/org/apache/tiles/el/ScopeELResolver.java
@@ -0,0 +1,138 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.el;
+
+import java.beans.FeatureDescriptor;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.el.ELContext;
+import javax.el.ELResolver;
+
+import org.apache.tiles.request.Request;
+
+/**
+ * Resolves beans in request, session and application scope.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.1
+ */
+public class ScopeELResolver extends ELResolver {
+
+    /**
+     * The length of the suffix: "Scope".
+     */
+    private static final int SUFFIX_LENGTH = 5;
+
+    /** {@inheritDoc} */
+    @Override
+    public Class<?> getCommonPropertyType(ELContext context, Object base) {
+        // only resolve at the root of the context
+        if (base != null) {
+            return null;
+        }
+
+        return Map.class;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context,
+            Object base) {
+        if (base != null) {
+            List<FeatureDescriptor> retValue = Collections.emptyList();
+            return retValue.iterator();
+        }
+
+        List<FeatureDescriptor> list = new ArrayList<FeatureDescriptor>();
+
+        Request request = (Request) context
+                .getContext(Request.class);
+        for (String scope : request.getAvailableScopes()) {
+            FeatureDescriptor descriptor = new FeatureDescriptor();
+            descriptor.setDisplayName(scope + "Scope");
+            descriptor.setExpert(false);
+            descriptor.setHidden(false);
+            descriptor.setName(scope + "Scope");
+            descriptor.setPreferred(true);
+            descriptor.setShortDescription("");
+            descriptor.setValue("type", Map.class);
+            descriptor.setValue("resolvableAtDesignTime", Boolean.FALSE);
+            list.add(descriptor);
+        }
+
+        return list.iterator();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Class<?> getType(ELContext context, Object base, Object property) {
+        if (base != null || property == null || !(property instanceof String)
+                || !((String) property).endsWith("Scope")) {
+            return null;
+        }
+
+        return Map.class;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Object getValue(ELContext context, Object base, Object property) {
+        if (base != null) {
+            return null;
+        }
+
+        Object retValue = null;
+        String propertyString = (String) property;
+        if (property instanceof String && propertyString.endsWith("Scope")) {
+            Request request = (Request) context
+                    .getContext(Request.class);
+            retValue = request.getContext(propertyString.substring(0,
+                    propertyString.length() - SUFFIX_LENGTH));
+        }
+
+        if (retValue != null) {
+            context.setPropertyResolved(true);
+        }
+
+        return retValue;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean isReadOnly(ELContext context, Object base, Object property) {
+        if (context == null) {
+            throw new NullPointerException();
+        }
+
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void setValue(ELContext context, Object base, Object property,
+            Object value) {
+        // Does nothing for the moment.
+    }
+}
diff --git a/Java-base/tiles/src/tiles-el/src/main/java/org/apache/tiles/el/TilesContextBeanELResolver.java b/Java-base/tiles/src/tiles-el/src/main/java/org/apache/tiles/el/TilesContextBeanELResolver.java
new file mode 100644
index 000000000..1cd3e1b32
--- /dev/null
+++ b/Java-base/tiles/src/tiles-el/src/main/java/org/apache/tiles/el/TilesContextBeanELResolver.java
@@ -0,0 +1,184 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.el;
+
+import java.beans.FeatureDescriptor;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.el.ELContext;
+import javax.el.ELResolver;
+
+import org.apache.tiles.request.Request;
+
+/**
+ * Resolves beans in request, session and application scope.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.1
+ */
+public class TilesContextBeanELResolver extends ELResolver {
+
+    /** {@inheritDoc} */
+    @Override
+    public Class<?> getCommonPropertyType(ELContext context, Object base) {
+        // only resolve at the root of the context
+        if (base != null) {
+            return null;
+        }
+
+        return String.class;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context,
+            Object base) {
+        List<FeatureDescriptor> list = new ArrayList<FeatureDescriptor>();
+
+        Request request = (Request) context
+                .getContext(Request.class);
+        for (String scope : request.getAvailableScopes()) {
+            collectBeanInfo(request.getContext(scope), list);
+        }
+        return list.iterator();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Class<?> getType(ELContext context, Object base, Object property) {
+        if (base != null) {
+            return null;
+        }
+
+        Object obj = findObjectByProperty(context, property);
+        if (obj != null) {
+            context.setPropertyResolved(true);
+            return obj.getClass();
+        }
+        return null;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Object getValue(ELContext context, Object base, Object property) {
+        if (base != null) {
+            return null;
+        }
+
+        Object retValue = findObjectByProperty(context, property);
+
+        if (retValue != null) {
+            context.setPropertyResolved(true);
+        }
+
+        return retValue;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean isReadOnly(ELContext context, Object base, Object property) {
+        if (context == null) {
+            throw new NullPointerException();
+        }
+
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void setValue(ELContext context, Object base, Object property,
+            Object value) {
+        // Does nothing for the moment.
+    }
+
+    /**
+     * Collects bean infos from a map's values and filling a list.
+     *
+     * @param map The map containing the bean to be inspected.
+     * @param list The list to fill.
+     * @since 2.2.1
+     */
+    protected void collectBeanInfo(Map<String, ? extends Object> map,
+            List<FeatureDescriptor> list) {
+        if (map == null || map.isEmpty()) {
+            return;
+        }
+
+        for (Map.Entry<String, ? extends Object> entry : map.entrySet()) {
+            FeatureDescriptor descriptor = new FeatureDescriptor();
+            descriptor.setDisplayName(entry.getKey());
+            descriptor.setExpert(false);
+            descriptor.setHidden(false);
+            descriptor.setName(entry.getKey());
+            descriptor.setPreferred(true);
+            descriptor.setShortDescription("");
+            descriptor.setValue("type", String.class);
+            descriptor.setValue("resolvableAtDesignTime", Boolean.FALSE);
+            list.add(descriptor);
+        }
+    }
+
+    /**
+     * Finds an object in request, session or application scope, in this order.
+     *
+     * @param context The context to use.
+     * @param property The property used as an attribute name.
+     * @return The found bean, if it exists, or <code>null</code> otherwise.
+     * @since 2.2.1
+     */
+    protected Object findObjectByProperty(ELContext context, Object property) {
+        Object retValue = null;
+
+        Request request = (Request) context
+                .getContext(Request.class);
+
+        String prop = property.toString();
+
+        String[] scopes = request.getAvailableScopes().toArray(new String[0]);
+        int i = 0;
+        do {
+            retValue = getObject(request.getContext(scopes[i]), prop);
+            i++;
+        } while (retValue == null && i < scopes.length);
+
+        return retValue;
+    }
+
+    /**
+     * Returns an object from a map in a null-safe manner.
+     *
+     * @param map The map to use.
+     * @param property The property to use as a key.
+     * @return The object, if present, or <code>null</code> otherwise.
+     * @since 2.2.1
+     */
+    protected Object getObject(Map<String, ? extends Object> map,
+            String property) {
+        Object retValue = null;
+        if (map != null) {
+            retValue = map.get(property);
+        }
+        return retValue;
+    }
+}
diff --git a/Java-base/tiles/src/tiles-el/src/main/java/org/apache/tiles/el/TilesContextELResolver.java b/Java-base/tiles/src/tiles-el/src/main/java/org/apache/tiles/el/TilesContextELResolver.java
new file mode 100644
index 000000000..d3b59cacb
--- /dev/null
+++ b/Java-base/tiles/src/tiles-el/src/main/java/org/apache/tiles/el/TilesContextELResolver.java
@@ -0,0 +1,155 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.el;
+
+import java.beans.FeatureDescriptor;
+import java.util.Iterator;
+
+import javax.el.ELContext;
+import javax.el.ELResolver;
+
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.Request;
+import org.apache.tiles.util.CombinedBeanInfo;
+
+/**
+ * Resolves properties of {@link Request} and
+ * {@link ApplicationContext}.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.1
+ */
+public class TilesContextELResolver extends ELResolver {
+
+    /**
+     * Internal bean resolver to resolve beans in any context.
+     */
+    private ELResolver beanElResolver;
+
+    /**
+     * Constructor.
+     *
+     * @param beanElResolver The used bean resolver.
+     */
+    public TilesContextELResolver(ELResolver beanElResolver) {
+        this.beanElResolver = beanElResolver;
+    }
+
+    /**
+     * The beaninfos about {@link Request} and {@link ApplicationContext}.
+     */
+    private CombinedBeanInfo requestBeanInfo = new CombinedBeanInfo(
+            Request.class, ApplicationContext.class);
+
+    /** {@inheritDoc} */
+    @Override
+    public Class<?> getCommonPropertyType(ELContext context, Object base) {
+        // only resolve at the root of the context
+        if (base != null) {
+            return null;
+        }
+
+        return String.class;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context,
+            Object base) {
+        // only resolve at the root of the context
+        if (base != null) {
+            return null;
+        }
+
+        return requestBeanInfo.getDescriptors().iterator();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Class<?> getType(ELContext context, Object base, Object property) {
+        // only resolve at the root of the context
+        if (base != null) {
+            return null;
+        }
+
+        Class<?> retValue = null;
+        if (requestBeanInfo.getProperties(Request.class).contains(property)) {
+            Request request = (Request) context
+                    .getContext(Request.class);
+            retValue = beanElResolver.getType(context, request, property);
+        } else if (requestBeanInfo.getProperties(ApplicationContext.class).contains(property)) {
+            ApplicationContext applicationContext = (ApplicationContext) context
+                    .getContext(ApplicationContext.class);
+            retValue = beanElResolver.getType(context, applicationContext, property);
+        }
+
+        if (retValue != null) {
+            context.setPropertyResolved(true);
+        }
+
+        return retValue;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public Object getValue(ELContext context, Object base, Object property) {
+        // only resolve at the root of the context
+        if (base != null) {
+            return null;
+        }
+
+        Object retValue = null;
+
+        if (requestBeanInfo.getProperties(Request.class).contains(property)) {
+            Request request = (Request) context
+                    .getContext(Request.class);
+            retValue = beanElResolver.getValue(context, request, property);
+        } else if (requestBeanInfo.getProperties(ApplicationContext.class)
+                .contains(property)) {
+            ApplicationContext applicationContext = (ApplicationContext) context
+                    .getContext(ApplicationContext.class);
+            retValue = beanElResolver.getValue(context, applicationContext, property);
+        }
+
+        if (retValue != null) {
+            context.setPropertyResolved(true);
+        }
+
+        return retValue;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public boolean isReadOnly(ELContext context, Object base, Object property) {
+        if (context == null) {
+            throw new NullPointerException();
+        }
+
+        return true;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void setValue(ELContext context, Object base, Object property,
+            Object value) {
+        // Does nothing for the moment.
+    }
+}
diff --git a/Java-base/tiles/src/tiles-el/src/main/java/org/apache/tiles/el/package-info.java b/Java-base/tiles/src/tiles-el/src/main/java/org/apache/tiles/el/package-info.java
new file mode 100644
index 000000000..01731df4c
--- /dev/null
+++ b/Java-base/tiles/src/tiles-el/src/main/java/org/apache/tiles/el/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * Attribute evaluator classes that can perform EL evaluation for attributes.
+ */
+package org.apache.tiles.el;
diff --git a/Java-base/tiles/src/tiles-el/src/site/site.xml b/Java-base/tiles/src/tiles-el/src/site/site.xml
new file mode 100644
index 000000000..ec3b4ec03
--- /dev/null
+++ b/Java-base/tiles/src/tiles-el/src/site/site.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<project name="Apache Tiles - EL Support">
+     <skin>
+        <groupId>org.apache.maven.skins</groupId>
+        <artifactId>maven-fluido-skin</artifactId>
+        <version>1.3.0</version>
+     </skin>
+     <custom>
+        <fluidoSkin>
+        <topBarEnabled>true</topBarEnabled>
+        <sideBarEnabled>false</sideBarEnabled>
+        <searchEnabled>true</searchEnabled>
+        <gitHub>
+            <projectId>apache/tiles</projectId>
+            <ribbonOrientation>right</ribbonOrientation>
+            <ribbonColor>darkblue</ribbonColor>
+        </gitHub>
+        </fluidoSkin>
+     </custom>
+    <bannerLeft>
+        <name>Apache Tiles&#8482;</name>
+        <src>http://tiles.apache.org/images/logo.png</src>
+        <href>http://tiles.apache.org</href>
+    </bannerLeft>
+    <bannerRight>
+        <name>Apache Software Foundation</name>
+        <src>http://struts.apache.org/images/asf-logo.gif</src>
+        <href>http://www.apache.org</href>
+    </bannerRight>
+    <body>
+
+        <menu name="Apache Tiles&#8482;">
+            <item
+                   name="Welcome"
+                   href="../../index.html"/>
+            <item
+                    name="Tiles 3.0.x"
+                    href="../../framework/index.html"/>
+            <item
+                    name="Autotag 1.0.x"
+                    href="../../tiles-autotag/index.html"/>
+            <item
+                    name="Request 1.0.x"
+                    href="../../tiles-request/index.html"/>
+            <item
+                   name="Security bulletins"
+                   href="../security/index.html"/>
+            <item
+                   name="Download"
+                   href="http://tiles.apache.org/download.html"/>
+        </menu>
+
+        <menu ref="modules" />
+        <menu ref="reports" />
+
+        <footer>
+            <div class="row span12">
+                Apache Tiles, Tiles, Apache, the Apache feather logo, and the Apache Tiles
+                project logos are trademarks of The Apache Software Foundation.
+            </div>
+        </footer>
+    </body>
+</project>
diff --git a/Java-base/tiles/src/tiles-el/src/test/java/org/apache/tiles/el/ELAttributeEvaluatorTest.java b/Java-base/tiles/src/tiles-el/src/test/java/org/apache/tiles/el/ELAttributeEvaluatorTest.java
new file mode 100644
index 000000000..82a47451e
--- /dev/null
+++ b/Java-base/tiles/src/tiles-el/src/test/java/org/apache/tiles/el/ELAttributeEvaluatorTest.java
@@ -0,0 +1,195 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.el;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.el.ArrayELResolver;
+import javax.el.BeanELResolver;
+import javax.el.CompositeELResolver;
+import javax.el.ELResolver;
+import javax.el.ListELResolver;
+import javax.el.MapELResolver;
+import javax.el.ResourceBundleELResolver;
+
+import junit.framework.TestCase;
+
+import org.apache.el.ExpressionFactoryImpl;
+import org.apache.tiles.Attribute;
+import org.apache.tiles.Expression;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.Request;
+import org.easymock.EasyMock;
+
+/**
+ * Tests {@link ELAttributeEvaluator}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ELAttributeEvaluatorTest extends TestCase {
+
+    /**
+     * The evaluator to test.
+     */
+    private ELAttributeEvaluator evaluator;
+
+    /**
+     * The request object to use.
+     */
+    private Request request;
+
+    /** {@inheritDoc} */
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        evaluator = new ELAttributeEvaluator();
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+        Map<String, Object> sessionScope = new HashMap<String, Object>();
+        Map<String, Object> applicationScope = new HashMap<String, Object>();
+        requestScope.put("object1", "value");
+        sessionScope.put("object2", new Integer(1));
+        applicationScope.put("object3", new Float(2.0));
+        requestScope.put("paulaBean", new PaulaBean());
+        request = EasyMock.createMock(Request.class);
+        EasyMock.expect(request.getContext("request")).andReturn(requestScope)
+                .anyTimes();
+        EasyMock.expect(request.getContext("session")).andReturn(sessionScope)
+                .anyTimes();
+        EasyMock.expect(request.getContext("application")).andReturn(
+                applicationScope).anyTimes();
+        EasyMock.expect(request.getAvailableScopes()).andReturn(
+                Arrays.asList(new String[] { "request", "session", "application" })).anyTimes();
+        ApplicationContext applicationContext = EasyMock
+                .createMock(ApplicationContext.class);
+        EasyMock.expect(request.getApplicationContext()).andReturn(
+                applicationContext).anyTimes();
+        EasyMock.replay(request, applicationContext);
+
+        evaluator.setExpressionFactory(new ExpressionFactoryImpl());
+        ELResolver elResolver = new CompositeELResolver() {
+            {
+                BeanELResolver beanElResolver = new BeanELResolver(false);
+                add(new ScopeELResolver());
+                add(new TilesContextELResolver(beanElResolver));
+                add(new TilesContextBeanELResolver());
+                add(new ArrayELResolver(false));
+                add(new ListELResolver(false));
+                add(new MapELResolver(false));
+                add(new ResourceBundleELResolver());
+                add(beanElResolver);
+            }
+        };
+        evaluator.setResolver(elResolver);
+    }
+
+    /**
+     * Tests
+     * {@link ELAttributeEvaluator#evaluate(Attribute, Request)}.
+     */
+    public void testEvaluate() {
+        Attribute attribute = new Attribute();
+        attribute.setExpressionObject(new Expression("${requestScope.object1}"));
+        assertEquals("The value is not correct", "value", evaluator.evaluate(
+                attribute, request));
+        attribute.setExpressionObject(new Expression("${sessionScope.object2}"));
+        assertEquals("The value is not correct", new Integer(1), evaluator
+                .evaluate(attribute, request));
+        attribute.setExpressionObject(new Expression("${applicationScope.object3}"));
+        assertEquals("The value is not correct", new Float(2.0), evaluator
+                .evaluate(attribute, request));
+        attribute.setExpressionObject(new Expression("${object1}"));
+        assertEquals("The value is not correct", "value", evaluator.evaluate(
+                attribute, request));
+        attribute.setExpressionObject(new Expression("${object2}"));
+        assertEquals("The value is not correct", new Integer(1), evaluator
+                .evaluate(attribute, request));
+        attribute.setExpressionObject(new Expression("${object3}"));
+        assertEquals("The value is not correct", new Float(2.0), evaluator
+                .evaluate(attribute, request));
+        attribute.setExpressionObject(new Expression("${paulaBean.paula}"));
+        assertEquals("The value is not correct", "Brillant", evaluator
+                .evaluate(attribute, request));
+        attribute.setExpressionObject(new Expression("String literal"));
+        assertEquals("The value is not correct", "String literal", evaluator
+                .evaluate(attribute, request));
+        attribute.setValue(new Integer(2));
+        assertEquals("The value is not correct", new Integer(2), evaluator
+                .evaluate(attribute, request));
+        attribute.setValue("${object1}");
+        assertEquals("The value has been evaluated", "${object1}", evaluator
+                .evaluate(attribute, request));
+    }
+
+    /**
+     * Tests
+     * {@link ELAttributeEvaluator#evaluate(String, Request)}.
+     */
+    public void testEvaluateString() {
+        String expression = "${requestScope.object1}";
+        assertEquals("The value is not correct", "value", evaluator.evaluate(
+                expression, request));
+        expression = "${sessionScope.object2}";
+        assertEquals("The value is not correct", new Integer(1), evaluator
+                .evaluate(expression, request));
+        expression = "${applicationScope.object3}";
+        assertEquals("The value is not correct", new Float(2.0), evaluator
+                .evaluate(expression, request));
+        expression = "${object1}";
+        assertEquals("The value is not correct", "value", evaluator.evaluate(
+                expression, request));
+        expression = "${object2}";
+        assertEquals("The value is not correct", new Integer(1), evaluator
+                .evaluate(expression, request));
+        expression = "${object3}";
+        assertEquals("The value is not correct", new Float(2.0), evaluator
+                .evaluate(expression, request));
+        expression = "${paulaBean.paula}";
+        assertEquals("The value is not correct", "Brillant", evaluator
+                .evaluate(expression, request));
+        expression = "String literal";
+        assertEquals("The value is not correct", expression, evaluator
+                .evaluate(expression, request));
+    }
+
+    /**
+     * This is The Brillant Paula Bean (sic) just like it was posted to:
+     * http://thedailywtf.com/Articles/The_Brillant_Paula_Bean.aspx
+     * I hope that there is no copyright on it.
+     */
+    public static class PaulaBean {
+
+        /**
+         * Paula is brillant, really.
+         */
+        private String paula = "Brillant";
+
+        /**
+         * Returns brillant.
+         *
+         * @return "Brillant".
+         */
+        public String getPaula() {
+            return paula;
+        }
+    }
+}
diff --git a/Java-base/tiles/src/tiles-el/src/test/java/org/apache/tiles/el/ELContextImplTest.java b/Java-base/tiles/src/tiles-el/src/test/java/org/apache/tiles/el/ELContextImplTest.java
new file mode 100644
index 000000000..520398ba3
--- /dev/null
+++ b/Java-base/tiles/src/tiles-el/src/test/java/org/apache/tiles/el/ELContextImplTest.java
@@ -0,0 +1,121 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.el;
+
+import static org.easymock.classextension.EasyMock.*;
+import static org.junit.Assert.*;
+
+import javax.el.ELResolver;
+import javax.el.FunctionMapper;
+import javax.el.ValueExpression;
+import javax.el.VariableMapper;
+
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests {@link ELContextImpl}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ELContextImplTest {
+
+    /**
+     * The EL context to test.
+     */
+    private ELContextImpl context;
+
+    /**
+     * The EL resolver.
+     */
+    private ELResolver resolver;
+
+    /**
+     * Sets up the test.
+     */
+    @Before
+    public void setUp() {
+        resolver = createMock(ELResolver.class);
+        context = new ELContextImpl(resolver);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.el.ELContextImpl#getELResolver()}.
+     */
+    @Test
+    public void testGetELResolver() {
+        replay(resolver);
+        assertEquals(resolver, context.getELResolver());
+        verify(resolver);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.el.ELContextImpl#setFunctionMapper(javax.el.FunctionMapper)}.
+     */
+    @Test
+    public void testSetFunctionMapper() {
+        FunctionMapper functionMapper = createMock(FunctionMapper.class);
+
+        replay(resolver, functionMapper);
+        context.setFunctionMapper(functionMapper);
+        assertEquals(functionMapper, context.getFunctionMapper());
+        verify(resolver, functionMapper);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.el.ELContextImpl#setVariableMapper(javax.el.VariableMapper)}.
+     */
+    @Test
+    public void testSetVariableMapper() {
+        VariableMapper variableMapper = createMock(VariableMapper.class);
+
+        replay(resolver, variableMapper);
+        context.setVariableMapper(variableMapper);
+        assertEquals(variableMapper, context.getVariableMapper());
+        verify(resolver, variableMapper);
+    }
+
+    /**
+     * Tests {@link ELContextImpl#getFunctionMapper()}.
+     */
+    @Test
+    public void testNullFunctionMapper() {
+        replay(resolver);
+        FunctionMapper functionMapper = context.getFunctionMapper();
+        assertNull(functionMapper.resolveFunction("whatever", "it_IT"));
+        verify(resolver);
+    }
+
+    /**
+     * Tests {@link ELContextImpl#getVariableMapper()}.
+     */
+    @Test
+    public void testVariableMapperImpl() {
+        ValueExpression expression = createMock(ValueExpression.class);
+
+        replay(resolver, expression);
+        VariableMapper variableMapper = context.getVariableMapper();
+        assertNull(variableMapper.resolveVariable("whatever"));
+        variableMapper.setVariable("var", expression);
+        assertEquals(expression, variableMapper.resolveVariable("var"));
+        verify(resolver, expression);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-el/src/test/java/org/apache/tiles/el/JspExpressionFactoryFactoryTest.java b/Java-base/tiles/src/tiles-el/src/test/java/org/apache/tiles/el/JspExpressionFactoryFactoryTest.java
new file mode 100644
index 000000000..65acdd27a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-el/src/test/java/org/apache/tiles/el/JspExpressionFactoryFactoryTest.java
@@ -0,0 +1,85 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.el;
+
+import static org.easymock.classextension.EasyMock.*;
+import static org.junit.Assert.*;
+
+import javax.el.ExpressionFactory;
+import javax.servlet.ServletContext;
+import javax.servlet.jsp.JspApplicationContext;
+import javax.servlet.jsp.JspFactory;
+
+import org.apache.tiles.request.ApplicationContext;
+import org.junit.Test;
+
+/**
+ * Tests {@link JspExpressionFactoryFactory}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class JspExpressionFactoryFactoryTest {
+
+    /**
+     * Test method for {@link org.apache.tiles.el.JspExpressionFactoryFactory#getExpressionFactory()}.
+     */
+    @Test
+    public void testGetExpressionFactory() {
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        ServletContext servletContext = createMock(ServletContext.class);
+        JspFactory jspFactory = createMock(JspFactory.class);
+        JspApplicationContext jspApplicationContext = createMock(JspApplicationContext.class);
+        ExpressionFactory expressionFactory = createMock(ExpressionFactory.class);
+
+        expect(applicationContext.getContext()).andReturn(servletContext);
+        expect(jspFactory.getJspApplicationContext(servletContext)).andReturn(jspApplicationContext);
+        expect(jspApplicationContext.getExpressionFactory()).andReturn(expressionFactory);
+
+        replay(applicationContext, servletContext, jspFactory,
+                jspApplicationContext, expressionFactory);
+        JspFactory.setDefaultFactory(jspFactory);
+        JspExpressionFactoryFactory factory = new JspExpressionFactoryFactory();
+        factory.setApplicationContext(applicationContext);
+        assertEquals(expressionFactory, factory.getExpressionFactory());
+        verify(applicationContext, servletContext, jspFactory,
+                jspApplicationContext, expressionFactory);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.el.JspExpressionFactoryFactory#getExpressionFactory()}.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testSetApplicationContextIllegal() {
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        Integer servletContext = new Integer(1);
+
+        expect(applicationContext.getContext()).andReturn(servletContext);
+
+        replay(applicationContext);
+        try {
+            JspExpressionFactoryFactory factory = new JspExpressionFactoryFactory();
+            factory.setApplicationContext(applicationContext);
+        } finally {
+            verify(applicationContext);
+        }
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-el/src/test/java/org/apache/tiles/el/ScopeELResolverTest.java b/Java-base/tiles/src/tiles-el/src/test/java/org/apache/tiles/el/ScopeELResolverTest.java
new file mode 100644
index 000000000..4a3ca1209
--- /dev/null
+++ b/Java-base/tiles/src/tiles-el/src/test/java/org/apache/tiles/el/ScopeELResolverTest.java
@@ -0,0 +1,173 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.el;
+
+import static org.easymock.classextension.EasyMock.*;
+import static org.junit.Assert.*;
+
+import java.beans.FeatureDescriptor;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.el.ELContext;
+
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.Request;
+import org.junit.Before;
+import org.junit.Test;
+
+
+/**
+ * Tests {@link ScopeELResolver}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ScopeELResolverTest {
+
+    /**
+     * The resolver to test.
+     */
+    private ScopeELResolver resolver;
+
+    /** {@inheritDoc} */
+    @Before
+    public void setUp() {
+        resolver = new ScopeELResolver();
+    }
+
+    /**
+     * Tests {@link ScopeELResolver#getCommonPropertyType(ELContext, Object)}.
+     */
+    @Test
+    public void testGetCommonPropertyType() {
+        ELContext elContext = createMock(ELContext.class);
+
+        replay(elContext);
+        assertNull(resolver.getCommonPropertyType(elContext, new Integer(1)));
+        assertEquals(Map.class, resolver.getCommonPropertyType(elContext, null));
+        verify(elContext);
+    }
+
+    /**
+     * Tests {@link ScopeELResolver#getFeatureDescriptors(ELContext, Object)}.
+     */
+    @Test
+    public void testGetFeatureDescriptors() {
+        ELContext elContext = createMock(ELContext.class);
+        Request request = createMock(Request.class);
+
+        expect(elContext.getContext(Request.class)).andReturn(request);
+        expect(request.getAvailableScopes()).andReturn(Arrays.asList(new String[] {"one", "two"}));
+
+        replay(elContext, request);
+        assertFalse(resolver.getFeatureDescriptors(elContext, new Integer(1)).hasNext());
+        Iterator<FeatureDescriptor> descriptors = resolver.getFeatureDescriptors(elContext, null);
+        FeatureDescriptor descriptor = descriptors.next();
+        assertEquals("oneScope", descriptor.getName());
+        descriptor = descriptors.next();
+        assertEquals("twoScope", descriptor.getName());
+        assertFalse(descriptors.hasNext());
+        verify(elContext, request);
+    }
+
+    /**
+     * Test method for
+     * {@link ScopeELResolver#getType(javax.el.ELContext, java.lang.Object, java.lang.Object)}.
+     */
+    @Test
+    public void testGetType() {
+        Request request = createMock(Request.class);
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        ELContext context = new ELContextImpl(resolver);
+        replay(request, applicationContext);
+        context.putContext(Request.class, request);
+        context.putContext(ApplicationContext.class, applicationContext);
+        assertNull(resolver.getType(context, new Integer(1), "whatever"));
+        assertEquals("The requestScope object is not a map.", Map.class,
+                resolver.getType(context, null, "requestScope"));
+        assertEquals("The sessionScope object is not a map.", Map.class,
+                resolver.getType(context, null, "sessionScope"));
+        assertEquals("The applicationScope object is not a map.", Map.class,
+                resolver.getType(context, null, "applicationScope"));
+    }
+
+    /**
+     * Test method for
+     * {@link ScopeELResolver#getValue(javax.el.ELContext, java.lang.Object, java.lang.Object)}.
+     */
+    @Test
+    public void testGetValue() {
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+        requestScope.put("objectKey", "objectValue");
+        Map<String, Object> sessionScope = new HashMap<String, Object>();
+        sessionScope.put("sessionObjectKey", "sessionObjectValue");
+        Map<String, Object> applicationScope = new HashMap<String, Object>();
+        applicationScope.put("applicationObjectKey", "applicationObjectValue");
+        Request request = createMock(Request.class);
+        expect(request.getContext("request")).andReturn(requestScope);
+        expect(request.getContext("session")).andReturn(sessionScope);
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        expect(request.getContext("application")).andReturn(applicationScope);
+        ELContext context = new ELContextImpl(resolver);
+        replay(request, applicationContext);
+        context.putContext(Request.class, request);
+        context.putContext(ApplicationContext.class, applicationContext);
+        assertNull(resolver.getValue(context, new Integer(1), "whatever"));
+        assertEquals("The requestScope map does not correspond", requestScope,
+                resolver.getValue(context, null, "requestScope"));
+        assertEquals("The sessionScope map does not correspond", sessionScope,
+                resolver.getValue(context, null, "sessionScope"));
+        assertEquals("The applicationScope map does not correspond",
+                applicationScope, resolver.getValue(context, null,
+                        "applicationScope"));
+    }
+
+    /**
+     * Tests {@link ScopeELResolver#isReadOnly(ELContext, Object, Object)}.
+     */
+    @Test
+    public void testIsReadOnly() {
+        ELContext elContext = createMock(ELContext.class);
+
+        replay(elContext);
+        assertTrue(resolver.isReadOnly(elContext, null, "whatever"));
+        verify(elContext);
+    }
+
+    /**
+     * Tests {@link ScopeELResolver#isReadOnly(ELContext, Object, Object)}.
+     */
+    @Test(expected=NullPointerException.class)
+    public void testIsReadOnlyNPE() {
+        resolver.isReadOnly(null, null, "whatever");
+    }
+
+    /**
+     * Tests {@link ScopeELResolver#setValue(ELContext, Object, Object, Object)}.
+     */
+    @Test
+    public void testSetValue() {
+        // Just to complete code coverage!
+        resolver.setValue(null, null, null, null);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-el/src/test/java/org/apache/tiles/el/TilesContextBeanELResolverTest.java b/Java-base/tiles/src/tiles-el/src/test/java/org/apache/tiles/el/TilesContextBeanELResolverTest.java
new file mode 100644
index 000000000..b282528ea
--- /dev/null
+++ b/Java-base/tiles/src/tiles-el/src/test/java/org/apache/tiles/el/TilesContextBeanELResolverTest.java
@@ -0,0 +1,299 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.el;
+
+import static org.easymock.classextension.EasyMock.*;
+import static org.junit.Assert.*;
+
+import java.beans.FeatureDescriptor;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.el.ELContext;
+
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.Request;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests {@link TilesContextBeanELResolver}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TilesContextBeanELResolverTest {
+
+    /**
+     * The resolver to test.
+     */
+    private TilesContextBeanELResolver resolver;
+
+    /**
+     * Sets up the test.
+     */
+    @Before
+    public void setUp() {
+        resolver = new TilesContextBeanELResolver();
+    }
+
+    /**
+     * Test method for
+     * {@link TilesContextBeanELResolver#getCommonPropertyType(javax.el.ELContext, java.lang.Object)}.
+     */
+    @Test
+    public void testGetCommonPropertyType() {
+        Class<?> clazz = resolver.getCommonPropertyType(null, null);
+        assertEquals("The class is not correct", String.class, clazz);
+        clazz = resolver.getCommonPropertyType(null, "Base object");
+        assertNull("The class for non root objects must be null", clazz);
+    }
+
+    /**
+     * Test method for
+     * {@link TilesContextBeanELResolver#getFeatureDescriptors(javax.el.ELContext, java.lang.Object)}.
+     */
+    @Test
+    public void testGetFeatureDescriptors() {
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+        Map<String, Object> sessionScope = new HashMap<String, Object>();
+        Map<String, Object> applicationScope = new HashMap<String, Object>();
+        requestScope.put("object1", "value");
+        sessionScope.put("object2", new Integer(1));
+        applicationScope.put("object3", new Float(2.0));
+        Request request = createMock(Request.class);
+        expect(request.getContext("request")).andReturn(requestScope)
+                .anyTimes();
+        expect(request.getContext("session")).andReturn(sessionScope)
+                .anyTimes();
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        expect(request.getContext("application")).andReturn(
+                applicationScope).anyTimes();
+        expect(request.getAvailableScopes()).andReturn(
+                Arrays.asList(new String[] { "request", "session", "application" }))
+                .anyTimes();
+        replay(request, applicationContext);
+
+        ELContext context = new ELContextImpl(resolver);
+        context.putContext(Request.class, request);
+        context.putContext(ApplicationContext.class, applicationContext);
+
+        List<FeatureDescriptor> expected = new ArrayList<FeatureDescriptor>();
+        resolver.collectBeanInfo(requestScope, expected);
+        resolver.collectBeanInfo(sessionScope, expected);
+        resolver.collectBeanInfo(applicationScope, expected);
+        Iterator<FeatureDescriptor> featureIt = resolver.getFeatureDescriptors(
+                context, null);
+        Iterator<FeatureDescriptor> expectedIt = expected.iterator();
+        while (featureIt.hasNext() && expectedIt.hasNext()) {
+            FeatureDescriptor expectedDescriptor = expectedIt.next();
+            FeatureDescriptor descriptor = featureIt.next();
+            assertEquals("The feature is not the same", expectedDescriptor
+                    .getDisplayName(), descriptor.getDisplayName());
+            assertEquals("The feature is not the same", expectedDescriptor
+                    .getName(), descriptor.getName());
+            assertEquals("The feature is not the same", expectedDescriptor
+                    .getShortDescription(), descriptor.getShortDescription());
+            assertEquals("The feature is not the same", expectedDescriptor
+                    .getValue("type"), descriptor.getValue("type"));
+            assertEquals("The feature is not the same", expectedDescriptor
+                    .getValue("resolvableAtDesignTime"), descriptor
+                    .getValue("resolvableAtDesignTime"));
+            assertEquals("The feature is not the same", expectedDescriptor
+                    .isExpert(), descriptor.isExpert());
+            assertEquals("The feature is not the same", expectedDescriptor
+                    .isHidden(), descriptor.isHidden());
+            assertEquals("The feature is not the same", expectedDescriptor
+                    .isPreferred(), descriptor.isPreferred());
+        }
+        assertTrue("The feature descriptors are not of the same size",
+                !featureIt.hasNext() && !expectedIt.hasNext());
+    }
+
+    /**
+     * Test method for
+     * {@link TilesContextBeanELResolver#getType(javax.el.ELContext, java.lang.Object, java.lang.Object)}.
+     */
+    @Test
+    public void testGetType() {
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+        Map<String, Object> sessionScope = new HashMap<String, Object>();
+        Map<String, Object> applicationScope = new HashMap<String, Object>();
+        requestScope.put("object1", "value");
+        sessionScope.put("object2", new Integer(1));
+        applicationScope.put("object3", new Float(2.0));
+        Request request = createMock(Request.class);
+        expect(request.getContext("request")).andReturn(requestScope)
+                .anyTimes();
+        expect(request.getContext("session")).andReturn(sessionScope)
+                .anyTimes();
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        expect(request.getContext("application")).andReturn(
+                applicationScope).anyTimes();
+        expect(request.getAvailableScopes()).andReturn(
+                Arrays.asList(new String[] { "request", "session", "application" }))
+                .anyTimes();
+        replay(request, applicationContext);
+
+        ELContext context = new ELContextImpl(resolver);
+        context.putContext(Request.class, request);
+        context.putContext(ApplicationContext.class, applicationContext);
+
+        assertEquals("The type is not correct", String.class, resolver.getType(
+                context, null, "object1"));
+        assertEquals("The type is not correct", Integer.class, resolver.getType(
+                context, null, "object2"));
+        assertEquals("The type is not correct", Float.class, resolver.getType(
+                context, null, "object3"));
+        assertNull(resolver.getType(context, new Integer(1), "whatever"));
+        assertNull(resolver.getType(context, null, "object4"));
+        verify(request, applicationContext);
+    }
+
+    /**
+     * Test method for
+     * {@link TilesContextBeanELResolver#getValue(javax.el.ELContext, java.lang.Object, java.lang.Object)}.
+     */
+    @Test
+    public void testGetValue() {
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+        Map<String, Object> sessionScope = new HashMap<String, Object>();
+        Map<String, Object> applicationScope = new HashMap<String, Object>();
+        requestScope.put("object1", "value");
+        sessionScope.put("object2", new Integer(1));
+        applicationScope.put("object3", new Float(2.0));
+        Request request = createMock(Request.class);
+        expect(request.getContext("request")).andReturn(requestScope)
+                .anyTimes();
+        expect(request.getContext("session")).andReturn(sessionScope)
+                .anyTimes();
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        expect(request.getContext("application")).andReturn(
+                applicationScope).anyTimes();
+        expect(request.getAvailableScopes()).andReturn(
+                Arrays.asList(new String[] { "request", "session", "application" }))
+                .anyTimes();
+        replay(request, applicationContext);
+
+        ELContext context = new ELContextImpl(resolver);
+        context.putContext(Request.class, request);
+        context.putContext(ApplicationContext.class, applicationContext);
+
+        assertEquals("The value is not correct", "value", resolver.getValue(
+                context, null, "object1"));
+        assertEquals("The value is not correct", new Integer(1), resolver
+                .getValue(context, null, "object2"));
+        assertEquals("The value is not correct", new Float(2.0), resolver
+                .getValue(context, null, "object3"));
+        assertNull(resolver.getValue(context, new Integer(1), "whatever"));
+    }
+
+    /**
+     * Test method for
+     * {@link TilesContextBeanELResolver#isReadOnly(javax.el.ELContext, java.lang.Object, java.lang.Object)}.
+     */
+    @Test
+    public void testIsReadOnlyELContextObjectObject() {
+        ELContext context = new ELContextImpl(resolver);
+        assertTrue("The value is not read only", resolver.isReadOnly(context,
+                null, null));
+    }
+
+    /**
+     * Test method for
+     * {@link TilesContextBeanELResolver#isReadOnly(javax.el.ELContext, java.lang.Object, java.lang.Object)}.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testIsReadOnlyNPE() {
+        resolver.isReadOnly(null, null, null);
+    }
+
+    /**
+     * Tests {@link TilesContextBeanELResolver#setValue(ELContext, Object, Object, Object)}.
+     */
+    @Test
+    public void testSetValue() {
+        // Just to complete code coverage!
+        resolver.setValue(null, null, null, null);
+    }
+
+    /**
+     * Test method for
+     * {@link TilesContextBeanELResolver#findObjectByProperty(javax.el.ELContext, java.lang.Object)}.
+     */
+    @Test
+    public void testFindObjectByProperty() {
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+        Map<String, Object> sessionScope = new HashMap<String, Object>();
+        Map<String, Object> applicationScope = new HashMap<String, Object>();
+        requestScope.put("object1", "value");
+        sessionScope.put("object2", new Integer(1));
+        applicationScope.put("object3", new Float(2.0));
+        Request request = createMock(Request.class);
+        expect(request.getContext("request")).andReturn(requestScope)
+                .anyTimes();
+        expect(request.getContext("session")).andReturn(sessionScope)
+                .anyTimes();
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        expect(request.getContext("application")).andReturn(
+                applicationScope).anyTimes();
+        expect(request.getAvailableScopes()).andReturn(
+                Arrays.asList(new String[] { "request", "session", "application" }))
+                .anyTimes();
+        replay(request, applicationContext);
+
+        ELContext context = new ELContextImpl(resolver);
+        context.putContext(Request.class, request);
+        context.putContext(ApplicationContext.class, applicationContext);
+
+        assertEquals("The value is not correct", "value", resolver
+                .findObjectByProperty(context, "object1"));
+        assertEquals("The value is not correct", new Integer(1), resolver
+                .findObjectByProperty(context, "object2"));
+        assertEquals("The value is not correct", new Float(2.0), resolver
+                .findObjectByProperty(context, "object3"));
+    }
+
+    /**
+     * Test method for
+     * {@link org.apache.tiles.el.TilesContextBeanELResolver#getObject(java.util.Map, java.lang.String)}.
+     */
+    @Test
+    public void testGetObject() {
+        Map<String, Object> map = new HashMap<String, Object>();
+        map.put("object1", "value");
+        assertEquals("The value is not correct", "value", resolver.getObject(
+                map, "object1"));
+        assertNull("The value is not null", resolver.getObject(map, "object2"));
+        assertNull("The value is not null", resolver.getObject(null, "object1"));
+    }
+
+    /**
+     * Tests {@link TilesContextBeanELResolver#collectBeanInfo(Map, List)}.
+     */
+    @Test
+    public void testCollectBeanInfoEmpty() {
+        resolver.collectBeanInfo(null, null);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-el/src/test/java/org/apache/tiles/el/TilesContextELResolverTest.java b/Java-base/tiles/src/tiles-el/src/test/java/org/apache/tiles/el/TilesContextELResolverTest.java
new file mode 100644
index 000000000..e781b97d4
--- /dev/null
+++ b/Java-base/tiles/src/tiles-el/src/test/java/org/apache/tiles/el/TilesContextELResolverTest.java
@@ -0,0 +1,188 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.el;
+
+import static org.easymock.classextension.EasyMock.*;
+import static org.junit.Assert.*;
+
+import java.beans.FeatureDescriptor;
+import java.beans.PropertyDescriptor;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import javax.el.ELContext;
+import javax.el.ELResolver;
+
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.Request;
+import org.apache.tiles.request.reflect.ClassUtil;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests {@link TilesContextELResolver}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TilesContextELResolverTest {
+
+    /**
+     * The bean resolver.
+     */
+    private ELResolver beanElResolver;
+
+    /**
+     * The resolver to test.
+     */
+    private TilesContextELResolver resolver;
+
+    /**
+     * Sets up the test.
+     */
+    @Before
+    public void setUp() {
+        beanElResolver = createMock(ELResolver.class);
+        resolver = new TilesContextELResolver(beanElResolver);
+    }
+
+    /**
+     * Test method for
+     * {@link TilesContextELResolver#getCommonPropertyType(javax.el.ELContext, java.lang.Object)}.
+     */
+    @Test
+    public void testGetCommonPropertyTypeELContextObject() {
+        replay(beanElResolver);
+        Class<?> clazz = resolver.getCommonPropertyType(null, null);
+        assertEquals("The class is not correct", String.class, clazz);
+        clazz = resolver.getCommonPropertyType(null, "Base object");
+        assertNull("The class for non root objects must be null", clazz);
+        verify(beanElResolver);
+    }
+
+    /**
+     * Test method for
+     * {@link TilesContextELResolver#getFeatureDescriptors(javax.el.ELContext, java.lang.Object)}.
+     */
+    @Test
+    public void testGetFeatureDescriptorsELContextObject() {
+        replay(beanElResolver);
+        assertNull(resolver.getFeatureDescriptors(null, new Integer(1)));
+        Map<String, PropertyDescriptor> expected = new LinkedHashMap<String, PropertyDescriptor>();
+        ClassUtil.collectBeanInfo(Request.class, expected);
+        ClassUtil.collectBeanInfo(ApplicationContext.class, expected);
+        Iterator<FeatureDescriptor> featureIt = resolver.getFeatureDescriptors(
+                null, null);
+        Iterator<? extends FeatureDescriptor> expectedIt = expected.values().iterator();
+        while (featureIt.hasNext() && expectedIt.hasNext()) {
+            assertEquals("The feature is not the same", expectedIt.next(),
+                    featureIt.next());
+        }
+        assertTrue("The feature descriptors are not of the same size",
+                !featureIt.hasNext() && !expectedIt.hasNext());
+        verify(beanElResolver);
+    }
+
+    /**
+     * Tests {@link TilesContextBeanELResolver#getType(ELContext, Object, Object)}.
+     */
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    @Test
+    public void testGetType() {
+        ELContext elContext = createMock(ELContext.class);
+        Request request = createMock(Request.class);
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+
+        expect(elContext.getContext(Request.class)).andReturn(request);
+        expect(elContext.getContext(ApplicationContext.class)).andReturn(applicationContext);
+        expect(beanElResolver.getType(elContext, request, "responseCommitted")).andReturn((Class) Boolean.class);
+        expect(beanElResolver.getType(elContext, applicationContext, "initParams")).andReturn((Class) Map.class);
+        elContext.setPropertyResolved(true);
+        expectLastCall().times(2);
+
+        replay(beanElResolver, elContext, request, applicationContext);
+        assertNull(resolver.getType(elContext, new Integer(1), "whatever"));
+        assertEquals(Boolean.class, resolver.getType(elContext, null, "responseCommitted"));
+        assertEquals(Map.class, resolver.getType(elContext, null, "initParams"));
+        verify(beanElResolver, elContext, request, applicationContext);
+    }
+
+    /**
+     * Tests {@link TilesContextBeanELResolver#getValue(ELContext, Object, Object)}.
+     */
+    @Test
+    public void testGetValue() {
+        ELContext elContext = createMock(ELContext.class);
+        Request request = createMock(Request.class);
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        @SuppressWarnings("rawtypes")
+        Map map = createMock(Map.class);
+
+        expect(elContext.getContext(Request.class)).andReturn(request);
+        expect(elContext.getContext(ApplicationContext.class)).andReturn(applicationContext);
+        expect(beanElResolver.getValue(elContext, request, "responseCommitted")).andReturn(true);
+        expect(beanElResolver.getValue(elContext, applicationContext, "initParams")).andReturn(map);
+        elContext.setPropertyResolved(true);
+        expectLastCall().times(2);
+
+        replay(beanElResolver, elContext, request, applicationContext, map);
+        assertNull(resolver.getValue(elContext, new Integer(1), "whatever"));
+        assertEquals(true, resolver.getValue(elContext, null, "responseCommitted"));
+        assertEquals(map, resolver.getValue(elContext, null, "initParams"));
+        verify(beanElResolver, elContext, request, applicationContext, map);
+    }
+
+    /**
+     * Test method for
+     * {@link TilesContextELResolver#isReadOnly(javax.el.ELContext, java.lang.Object, java.lang.Object)}.
+     */
+    @Test
+    public void testIsReadOnly() {
+        replay(beanElResolver);
+        ELContext context = new ELContextImpl(resolver);
+        assertTrue("The value is not read only", resolver.isReadOnly(context,
+                null, null));
+        verify(beanElResolver);
+    }
+
+    /**
+     * Test method for
+     * {@link TilesContextELResolver#isReadOnly(javax.el.ELContext, java.lang.Object, java.lang.Object)}.
+     */
+    @Test(expected = NullPointerException.class)
+    public void testIsReadOnlyNPE() {
+        replay(beanElResolver);
+        try {
+            resolver.isReadOnly(null, null, null);
+        } finally {
+            verify(beanElResolver);
+        }
+    }
+
+    /**
+     * Tests {@link TilesContextELResolver#setValue(ELContext, Object, Object, Object)}.
+     */
+    @Test
+    public void testSetValue() {
+        // Just to complete code coverage!
+        resolver.setValue(null, null, null, null);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-extras/pom.xml b/Java-base/tiles/src/tiles-extras/pom.xml
new file mode 100644
index 000000000..1d471d6d4
--- /dev/null
+++ b/Java-base/tiles/src/tiles-extras/pom.xml
@@ -0,0 +1,169 @@
+<?xml version="1.0"?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+  <parent>
+    <groupId>org.apache.tiles</groupId>
+    <artifactId>tiles-parent</artifactId>
+    <version>3.1-SNAPSHOT</version>
+  </parent>
+
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>tiles-extras</artifactId>
+  <packaging>jar</packaging>
+  <name>Tiles - Extras</name>
+  <description>Extras for Tiles, including non-standard, non-generic, non-identifiable components that may be useful for Tiles users.
+  </description>
+
+  <properties>
+  	<tiles.osgi.symbolicName>org.apache.tiles.extras</tiles.osgi.symbolicName>
+      <!-- decrease this whenever possible -->
+      <checkstyle.maxAllowedViolations>21</checkstyle.maxAllowedViolations>
+  </properties>
+
+  <build>
+    <resources>
+      <resource>
+        <directory>src/main/resources</directory>
+        <excludes>
+          <exclude>LICENSE.txt</exclude>
+          <exclude>NOTICE.txt</exclude>
+        </excludes>
+      </resource>
+      <resource>
+        <directory>src/main/resources</directory>
+        <includes>
+          <include>LICENSE.txt</include>
+          <include>NOTICE.txt</include>
+        </includes>
+        <targetPath>META-INF</targetPath>
+      </resource>
+    </resources>
+  </build>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.tiles</groupId>
+      <artifactId>tiles-core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tiles</groupId>
+      <artifactId>tiles-request-servlet-wildcard</artifactId>
+      <version>${tiles.request.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tiles</groupId>
+      <artifactId>tiles-request-mustache</artifactId>
+      <version>${tiles.request.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tiles</groupId>
+      <artifactId>tiles-jsp</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tiles</groupId>
+      <artifactId>tiles-freemarker</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tiles</groupId>
+      <artifactId>tiles-velocity</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tiles</groupId>
+      <artifactId>tiles-el</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tiles</groupId>
+      <artifactId>tiles-mvel</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tiles</groupId>
+      <artifactId>tiles-ognl</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tiles</groupId>
+      <artifactId>tiles-compat</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+
+    <dependency>
+      <artifactId>guava</artifactId>
+      <groupId>com.google.guava</groupId>
+      <version>12.0.1</version>
+    </dependency>
+
+    <dependency>
+      <groupId>javax.servlet</groupId>
+      <artifactId>servlet-api</artifactId>
+      <scope>provided</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>javax.servlet.jsp</groupId>
+      <artifactId>jsp-api</artifactId>
+      <scope>provided</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>jcl-over-slf4j</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-jdk14</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.easymock</groupId>
+      <artifactId>easymock</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.easymock</groupId>
+      <artifactId>easymockclassextension</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/Java-base/tiles/src/tiles-extras/src/main/java/org/apache/tiles/extras/complete/CompleteAutoloadTilesContainerFactory.java b/Java-base/tiles/src/tiles-extras/src/main/java/org/apache/tiles/extras/complete/CompleteAutoloadTilesContainerFactory.java
new file mode 100644
index 000000000..6831ce209
--- /dev/null
+++ b/Java-base/tiles/src/tiles-extras/src/main/java/org/apache/tiles/extras/complete/CompleteAutoloadTilesContainerFactory.java
@@ -0,0 +1,296 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.extras.complete;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Locale;
+import java.util.regex.Pattern;
+
+import javax.el.ArrayELResolver;
+import javax.el.BeanELResolver;
+import javax.el.CompositeELResolver;
+import javax.el.ELResolver;
+import javax.el.ListELResolver;
+import javax.el.MapELResolver;
+import javax.el.ResourceBundleELResolver;
+
+import ognl.OgnlException;
+import ognl.OgnlRuntime;
+import ognl.PropertyAccessor;
+
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.compat.definition.digester.CompatibilityDigesterDefinitionsReader;
+import org.apache.tiles.context.TilesRequestContextHolder;
+import org.apache.tiles.definition.DefinitionsReader;
+import org.apache.tiles.definition.pattern.DefinitionPatternMatcherFactory;
+import org.apache.tiles.definition.pattern.PatternDefinitionResolver;
+import org.apache.tiles.definition.pattern.PrefixedPatternDefinitionResolver;
+import org.apache.tiles.definition.pattern.regexp.RegexpDefinitionPatternMatcherFactory;
+import org.apache.tiles.definition.pattern.wildcard.WildcardDefinitionPatternMatcherFactory;
+import org.apache.tiles.el.ELAttributeEvaluator;
+import org.apache.tiles.el.JspExpressionFactoryFactory;
+import org.apache.tiles.el.ScopeELResolver;
+import org.apache.tiles.el.TilesContextBeanELResolver;
+import org.apache.tiles.el.TilesContextELResolver;
+import org.apache.tiles.evaluator.AttributeEvaluatorFactory;
+import org.apache.tiles.evaluator.BasicAttributeEvaluatorFactory;
+import org.apache.tiles.factory.BasicTilesContainerFactory;
+import org.apache.tiles.factory.TilesContainerFactoryException;
+import org.apache.tiles.freemarker.TilesSharedVariableFactory;
+import org.apache.tiles.impl.mgmt.CachingTilesContainer;
+import org.apache.tiles.locale.LocaleResolver;
+import org.apache.tiles.mvel.MVELAttributeEvaluator;
+import org.apache.tiles.mvel.ScopeVariableResolverFactory;
+import org.apache.tiles.mvel.TilesContextBeanVariableResolverFactory;
+import org.apache.tiles.mvel.TilesContextVariableResolverFactory;
+import org.apache.tiles.ognl.AnyScopePropertyAccessor;
+import org.apache.tiles.ognl.DelegatePropertyAccessor;
+import org.apache.tiles.ognl.NestedObjectDelegatePropertyAccessor;
+import org.apache.tiles.ognl.OGNLAttributeEvaluator;
+import org.apache.tiles.ognl.PropertyAccessorDelegateFactory;
+import org.apache.tiles.ognl.ScopePropertyAccessor;
+import org.apache.tiles.ognl.TilesApplicationContextNestedObjectExtractor;
+import org.apache.tiles.ognl.TilesContextPropertyAccessorDelegateFactory;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.ApplicationResource;
+import org.apache.tiles.request.Request;
+import org.apache.tiles.request.freemarker.render.FreemarkerRenderer;
+import org.apache.tiles.request.freemarker.render.FreemarkerRendererBuilder;
+import org.apache.tiles.request.freemarker.servlet.SharedVariableLoaderFreemarkerServlet;
+import org.apache.tiles.request.mustache.MustacheRenderer;
+import org.apache.tiles.request.render.BasicRendererFactory;
+import org.apache.tiles.request.render.ChainedDelegateRenderer;
+import org.apache.tiles.request.render.Renderer;
+import org.apache.tiles.request.servlet.ServletUtil;
+import org.apache.tiles.request.velocity.render.VelocityRenderer;
+import org.apache.tiles.request.velocity.render.VelocityRendererBuilder;
+import org.mvel2.integration.VariableResolverFactory;
+
+/**
+ * Tiles container factory that:
+ * <ul>
+ * <li>create supporting objects for Velocity and FreeMarker;</li>
+ * <li>create renderers for Velocity, FreeMarker, and Mustache templates;</li>
+ * <li>allows using EL, MVEL and OGNL as attribute expressions;</li>
+ * <li>allows using Wildcards and Regular Expressions in definition names;</li>
+ * <li>loads Tiles 1.x definition files;</li>
+ * <li>loads all the definition files that have the "tiles*.xml" pattern under
+ * <code>/WEB-INF</code> directory (and subdirectories) and under
+ * <code>META-INF</code> directories (and subdirectories) in every jar.</li>
+ * </ul>
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public class CompleteAutoloadTilesContainerFactory extends BasicTilesContainerFactory {
+
+    /**
+     * The freemarker renderer name.
+     */
+    private static final String FREEMARKER_RENDERER_NAME = "freemarker";
+
+    /**
+     * The velocity renderer name.
+     */
+    private static final String VELOCITY_RENDERER_NAME = "velocity";
+
+    /**
+     * The mustache renderer name.
+     */
+    private static final String MUSTACHE_RENDERER_NAME = "mustache";
+
+    /** {@inheritDoc} */
+    @Override
+    public TilesContainer createDecoratedContainer(TilesContainer originalContainer,
+            ApplicationContext applicationContext) {
+        return new CachingTilesContainer(originalContainer);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected void registerAttributeRenderers(
+            final BasicRendererFactory rendererFactory,
+            final ApplicationContext applicationContext,
+            final TilesContainer container,
+            final AttributeEvaluatorFactory attributeEvaluatorFactory) {
+        super.registerAttributeRenderers(rendererFactory, applicationContext, container, attributeEvaluatorFactory);
+
+        FreemarkerRenderer freemarkerRenderer = FreemarkerRendererBuilder
+                .createInstance()
+                .setApplicationContext(applicationContext)
+                .setParameter("TemplatePath", "/")
+                .setParameter("NoCache", "true")
+                .setParameter("ContentType", "text/html")
+                .setParameter("template_update_delay", "0")
+                .setParameter("default_encoding", "ISO-8859-1")
+                .setParameter("number_format", "0.##########")
+                .setParameter(SharedVariableLoaderFreemarkerServlet.CUSTOM_SHARED_VARIABLE_FACTORIES_INIT_PARAM,
+                        "tiles," + TilesSharedVariableFactory.class.getName()).build();
+        rendererFactory.registerRenderer(FREEMARKER_RENDERER_NAME, freemarkerRenderer);
+
+        VelocityRenderer velocityRenderer = VelocityRendererBuilder.createInstance()
+                .setApplicationContext(applicationContext).build();
+        rendererFactory.registerRenderer(VELOCITY_RENDERER_NAME, velocityRenderer);
+
+        MustacheRenderer mustacheRenderer = new MustacheRenderer();
+        mustacheRenderer.setAcceptPattern(Pattern.compile(".+\\.mustache"));
+        rendererFactory.registerRenderer(MUSTACHE_RENDERER_NAME, mustacheRenderer);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected Renderer createDefaultAttributeRenderer(BasicRendererFactory rendererFactory,
+            ApplicationContext applicationContext, TilesContainer container,
+            AttributeEvaluatorFactory attributeEvaluatorFactory) {
+
+        ChainedDelegateRenderer retValue = new ChainedDelegateRenderer();
+        retValue.addAttributeRenderer(rendererFactory.getRenderer(DEFINITION_RENDERER_NAME));
+        retValue.addAttributeRenderer(rendererFactory.getRenderer(VELOCITY_RENDERER_NAME));
+        retValue.addAttributeRenderer(rendererFactory.getRenderer(FREEMARKER_RENDERER_NAME));
+        retValue.addAttributeRenderer(rendererFactory.getRenderer(MUSTACHE_RENDERER_NAME));
+        retValue.addAttributeRenderer(rendererFactory.getRenderer(TEMPLATE_RENDERER_NAME));
+        retValue.addAttributeRenderer(rendererFactory.getRenderer(STRING_RENDERER_NAME));
+        return retValue;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected AttributeEvaluatorFactory createAttributeEvaluatorFactory(ApplicationContext applicationContext,
+            LocaleResolver resolver) {
+        BasicAttributeEvaluatorFactory attributeEvaluatorFactory = new BasicAttributeEvaluatorFactory(
+                createELEvaluator(applicationContext));
+        attributeEvaluatorFactory.registerAttributeEvaluator("MVEL", createMVELEvaluator());
+        attributeEvaluatorFactory.registerAttributeEvaluator("OGNL", createOGNLEvaluator());
+
+        return attributeEvaluatorFactory;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected <T> PatternDefinitionResolver<T> createPatternDefinitionResolver(Class<T> customizationKeyClass) {
+        DefinitionPatternMatcherFactory wildcardFactory = new WildcardDefinitionPatternMatcherFactory();
+        DefinitionPatternMatcherFactory regexpFactory = new RegexpDefinitionPatternMatcherFactory();
+        PrefixedPatternDefinitionResolver<T> resolver = new PrefixedPatternDefinitionResolver<T>();
+        resolver.registerDefinitionPatternMatcherFactory("WILDCARD", wildcardFactory);
+        resolver.registerDefinitionPatternMatcherFactory("REGEXP", regexpFactory);
+        return resolver;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected List<ApplicationResource> getSources(ApplicationContext applicationContext) {
+        Collection<ApplicationResource> webINFSet = applicationContext.getResources("/WEB-INF/**/tiles*.xml");
+        Collection<ApplicationResource> metaINFSet = applicationContext
+                .getResources("classpath*:META-INF/**/tiles*.xml");
+
+        List<ApplicationResource> filteredResources = new ArrayList<ApplicationResource>();
+        if (webINFSet != null) {
+            for (ApplicationResource resource : webINFSet) {
+                if (Locale.ROOT.equals(resource.getLocale())) {
+                    filteredResources.add(resource);
+                }
+            }
+        }
+        if (metaINFSet != null) {
+            for (ApplicationResource resource : metaINFSet) {
+                if (Locale.ROOT.equals(resource.getLocale())) {
+                    filteredResources.add(resource);
+                }
+            }
+        }
+        return filteredResources;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected DefinitionsReader createDefinitionsReader(ApplicationContext applicationContext) {
+        return new CompatibilityDigesterDefinitionsReader();
+    }
+
+    /**
+     * Creates the EL evaluator.
+     *
+     * @param applicationContext The Tiles application context.
+     * @return The EL evaluator.
+     */
+    private ELAttributeEvaluator createELEvaluator(ApplicationContext applicationContext) {
+        ELAttributeEvaluator evaluator = new ELAttributeEvaluator();
+        JspExpressionFactoryFactory efFactory = new JspExpressionFactoryFactory();
+        efFactory.setApplicationContext(applicationContext);
+        evaluator.setExpressionFactory(efFactory.getExpressionFactory());
+        ELResolver elResolver = new CompositeELResolver() {
+            {
+                BeanELResolver beanElResolver = new BeanELResolver(false);
+                add(new ScopeELResolver());
+                add(new TilesContextELResolver(beanElResolver));
+                add(new TilesContextBeanELResolver());
+                add(new ArrayELResolver(false));
+                add(new ListELResolver(false));
+                add(new MapELResolver(false));
+                add(new ResourceBundleELResolver());
+                add(beanElResolver);
+            }
+        };
+        evaluator.setResolver(elResolver);
+        return evaluator;
+    }
+
+    /**
+     * Creates the MVEL evaluator.
+     *
+     * @return The MVEL evaluator.
+     */
+    private MVELAttributeEvaluator createMVELEvaluator() {
+        TilesRequestContextHolder requestHolder = new TilesRequestContextHolder();
+        VariableResolverFactory variableResolverFactory = new ScopeVariableResolverFactory(requestHolder);
+        variableResolverFactory.setNextFactory(new TilesContextVariableResolverFactory(requestHolder));
+        variableResolverFactory.setNextFactory(new TilesContextBeanVariableResolverFactory(requestHolder));
+        MVELAttributeEvaluator mvelEvaluator = new MVELAttributeEvaluator(requestHolder, variableResolverFactory);
+        return mvelEvaluator;
+    }
+
+    /**
+     * Creates the OGNL evaluator.
+     *
+     * @return The OGNL evaluator.
+     */
+    private OGNLAttributeEvaluator createOGNLEvaluator() {
+        try {
+            PropertyAccessor objectPropertyAccessor = OgnlRuntime.getPropertyAccessor(Object.class);
+            PropertyAccessor applicationContextPropertyAccessor = new NestedObjectDelegatePropertyAccessor<Request>(
+                    new TilesApplicationContextNestedObjectExtractor(), objectPropertyAccessor);
+            PropertyAccessor anyScopePropertyAccessor = new AnyScopePropertyAccessor();
+            PropertyAccessor scopePropertyAccessor = new ScopePropertyAccessor();
+            PropertyAccessorDelegateFactory<Request> factory = new TilesContextPropertyAccessorDelegateFactory(
+                    objectPropertyAccessor, applicationContextPropertyAccessor, anyScopePropertyAccessor,
+                    scopePropertyAccessor);
+            PropertyAccessor tilesRequestAccessor = new DelegatePropertyAccessor<Request>(factory);
+            OgnlRuntime.setPropertyAccessor(Request.class, tilesRequestAccessor);
+            return new OGNLAttributeEvaluator();
+        } catch (OgnlException e) {
+            throw new TilesContainerFactoryException("Cannot initialize OGNL evaluator", e);
+        }
+    }
+}
diff --git a/Java-base/tiles/src/tiles-extras/src/main/java/org/apache/tiles/extras/complete/CompleteAutoloadTilesInitializer.java b/Java-base/tiles/src/tiles-extras/src/main/java/org/apache/tiles/extras/complete/CompleteAutoloadTilesInitializer.java
new file mode 100644
index 000000000..8cb432874
--- /dev/null
+++ b/Java-base/tiles/src/tiles-extras/src/main/java/org/apache/tiles/extras/complete/CompleteAutoloadTilesInitializer.java
@@ -0,0 +1,56 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.extras.complete;
+
+import javax.servlet.ServletContext;
+
+import org.apache.tiles.factory.AbstractTilesContainerFactory;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.servlet.wildcard.WildcardServletApplicationContext;
+import org.apache.tiles.startup.AbstractTilesInitializer;
+
+/**
+ * This initializer uses {@link WildcardServletApplicationContext} to
+ * retrieve resources using Ant-style patterns and creates a
+ * {@link CompleteAutoloadTilesContainerFactory} to load all new features of
+ * Tiles at once.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public class CompleteAutoloadTilesInitializer extends AbstractTilesInitializer {
+
+    /** {@inheritDoc} */
+    @Override
+    protected ApplicationContext createTilesApplicationContext(
+            ApplicationContext preliminaryContext) {
+        return new WildcardServletApplicationContext(
+                (ServletContext) preliminaryContext.getContext());
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected AbstractTilesContainerFactory createContainerFactory(
+            ApplicationContext context) {
+        return new CompleteAutoloadTilesContainerFactory();
+    }
+}
diff --git a/Java-base/tiles/src/tiles-extras/src/main/java/org/apache/tiles/extras/complete/CompleteAutoloadTilesListener.java b/Java-base/tiles/src/tiles-extras/src/main/java/org/apache/tiles/extras/complete/CompleteAutoloadTilesListener.java
new file mode 100644
index 000000000..8d500ef12
--- /dev/null
+++ b/Java-base/tiles/src/tiles-extras/src/main/java/org/apache/tiles/extras/complete/CompleteAutoloadTilesListener.java
@@ -0,0 +1,41 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.extras.complete;
+
+import org.apache.tiles.startup.TilesInitializer;
+import org.apache.tiles.web.startup.AbstractTilesListener;
+
+/**
+ * Tiles listener that executes {@link CompleteAutoloadTilesInitializer}.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public class CompleteAutoloadTilesListener extends AbstractTilesListener {
+
+    /** {@inheritDoc} */
+    @Override
+    protected TilesInitializer createTilesInitializer() {
+        return new CompleteAutoloadTilesInitializer();
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-extras/src/main/java/org/apache/tiles/extras/complete/package-info.java b/Java-base/tiles/src/tiles-extras/src/main/java/org/apache/tiles/extras/complete/package-info.java
new file mode 100644
index 000000000..ee7db1438
--- /dev/null
+++ b/Java-base/tiles/src/tiles-extras/src/main/java/org/apache/tiles/extras/complete/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * These classes allow to start up Tiles with all features on.
+ */
+package org.apache.tiles.extras.complete;
diff --git a/Java-base/tiles/src/tiles-extras/src/main/java/org/apache/tiles/extras/module/ModularTilesInitializer.java b/Java-base/tiles/src/tiles-extras/src/main/java/org/apache/tiles/extras/module/ModularTilesInitializer.java
new file mode 100644
index 000000000..adf4f18a3
--- /dev/null
+++ b/Java-base/tiles/src/tiles-extras/src/main/java/org/apache/tiles/extras/module/ModularTilesInitializer.java
@@ -0,0 +1,111 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.extras.module;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+
+import javax.servlet.ServletContext;
+
+import org.apache.tiles.definition.DefinitionsFactoryException;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.ApplicationResource;
+import org.apache.tiles.request.reflect.ClassUtil;
+import org.apache.tiles.request.servlet.wildcard.WildcardServletApplicationContext;
+import org.apache.tiles.startup.TilesInitializer;
+
+/**
+ * Loads Tiles modules, initializes them and destroy them at the end.<br>
+ * It loads all META-INF/MANIFEST.MF files, checks for the "Tiles-Initializer"
+ * property that must contain a valid class name of a {@link TilesInitializer}.
+ * After that, initializes all found initializers, one by one. When the
+ * {@link #destroy()} method is called, all the initializers are then destroyed.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.1
+ */
+public class ModularTilesInitializer implements TilesInitializer {
+
+    /**
+     * The initializers to use.
+     */
+    private List<TilesInitializer> initializers;
+
+    /** {@inheritDoc} */
+    public void initialize(ApplicationContext preliminaryContext) {
+        ApplicationContext applicationContext = new WildcardServletApplicationContext(
+                (ServletContext) preliminaryContext.getContext());
+        loadInitializers(applicationContext);
+
+        for (TilesInitializer initializer : initializers) {
+            initializer.initialize(preliminaryContext);
+        }
+    }
+
+    /** {@inheritDoc} */
+    public void destroy() {
+        for (TilesInitializer initializer : initializers) {
+            initializer.destroy();
+        }
+    }
+
+    /**
+     * Load all the initializers from manifest files.
+     *
+     * @param applicationContext The application context.
+     */
+    private void loadInitializers(ApplicationContext applicationContext) {
+        initializers = new ArrayList<TilesInitializer>();
+        try {
+            Collection<ApplicationResource> resources = applicationContext
+                    .getResources("classpath*:META-INF/MANIFEST.MF");
+            ApplicationResource mainResource = applicationContext.getResource("/META-INF/MANIFEST.MF");
+            if (mainResource != null) {
+                resources.add(mainResource);
+            }
+            for (ApplicationResource resource : resources) {
+                InputStream stream = resource.getInputStream();
+                try {
+                    Manifest manifest = new Manifest(stream);
+                    Attributes attributes = manifest.getMainAttributes();
+                    if (attributes != null) {
+                        String initializerName = attributes.getValue("Tiles-Initializer");
+                        if (initializerName != null) {
+                            TilesInitializer initializer = (TilesInitializer) ClassUtil
+                                    .instantiate(initializerName);
+                            initializers.add(initializer);
+                        }
+                    }
+                } finally {
+                    stream.close();
+                }
+            }
+        } catch (IOException e) {
+            throw new DefinitionsFactoryException("Error getting manifest files", e);
+        }
+    }
+}
diff --git a/Java-base/tiles/src/tiles-extras/src/main/java/org/apache/tiles/extras/module/ModularTilesListener.java b/Java-base/tiles/src/tiles-extras/src/main/java/org/apache/tiles/extras/module/ModularTilesListener.java
new file mode 100644
index 000000000..9881e9c53
--- /dev/null
+++ b/Java-base/tiles/src/tiles-extras/src/main/java/org/apache/tiles/extras/module/ModularTilesListener.java
@@ -0,0 +1,41 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.extras.module;
+
+import org.apache.tiles.startup.TilesInitializer;
+import org.apache.tiles.web.startup.AbstractTilesListener;
+
+/**
+ * Tiles listener that executes {@link ModularTilesInitializer}.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.1
+ */
+public class ModularTilesListener extends AbstractTilesListener {
+
+    /** {@inheritDoc} */
+    @Override
+    protected TilesInitializer createTilesInitializer() {
+        return new ModularTilesInitializer();
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-extras/src/main/java/org/apache/tiles/extras/module/package-info.java b/Java-base/tiles/src/tiles-extras/src/main/java/org/apache/tiles/extras/module/package-info.java
new file mode 100644
index 000000000..fc44b2b16
--- /dev/null
+++ b/Java-base/tiles/src/tiles-extras/src/main/java/org/apache/tiles/extras/module/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * These classes allow to initialize independent module of Tiles.
+ */
+package org.apache.tiles.extras.module;
diff --git a/Java-base/tiles/src/tiles-extras/src/main/java/org/apache/tiles/extras/renderer/OptionsRenderer.java b/Java-base/tiles/src/tiles-extras/src/main/java/org/apache/tiles/extras/renderer/OptionsRenderer.java
new file mode 100644
index 000000000..b387fd7e5
--- /dev/null
+++ b/Java-base/tiles/src/tiles-extras/src/main/java/org/apache/tiles/extras/renderer/OptionsRenderer.java
@@ -0,0 +1,203 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.extras.renderer;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import org.apache.tiles.Attribute;
+import org.apache.tiles.ListAttribute;
+import org.apache.tiles.access.TilesAccess;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.Request;
+import org.apache.tiles.request.render.Renderer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Provides a custom "options" syntax for attributes.
+ * The first option that can be rendered is.
+ * Comes from <a href="http://tech.finn.no/the-ultimate-view/">The Ultimate View</a> article.<p/>
+ *
+ * Actual rendering is delegated to the TypeDetectingRenderer that's supplied in the constructor.<p/>
+ *
+ * For example:
+ * "/WEB-INF/tiles/fragments/${options[myoptions]}/content.jsp"
+ * given the myptions list-attribute is defined like:
+ * <pre>
+        &lt;put-list-attribute name="myoptions">
+            &lt;add-list-attribute>
+                &lt;add-attribute value="car"/>
+                &lt;add-attribute value="vechile"/>
+                &lt;add-attribute value="advert"/>
+            &lt;/add-list-attribute>
+        &lt;/put-list-attribute>
+   </pre>
+ * will look for content.jsp <br/>
+ * first in "/WEB-INF/tiles/fragments/car/" then <br/>
+ * second in "/WEB-INF/tiles/fragments/vechile/" and <br/>
+ * last in "/WEB-INF/tiles/fragments/advert".
+ * <p/>
+ * <p/>
+ * Currently only supports one occurrance of such an "option" pattern in the attribute's value.
+ * <p/>
+ * Limitation: "looking" for templates is implemented using applicationContext.getResource(..)
+ * therefore the option values in the options list need to be visible as applicationResources.
+ * <p/>
+ * The attribute found and rendered is cached so to improve performance on subsequent lookups.
+ * The default cache time-to-live is {@value #DEFAULT_CACHE_LIFE}, specified by {@link #DEFAULT_CACHE_LIFE}.
+ * It can be customised by setting the system property {@value #CACHE_LIFE_PROPERTY}, see {@link #CACHE_LIFE_PROPERTY}.
+ * Setting it to zero will disable the cache.
+ */
+public final class OptionsRenderer implements Renderer {
+
+    public static final String CACHE_LIFE_PROPERTY = OptionsRenderer.class.getName() + ".cache_ttl_ms";
+
+    public static final long DEFAULT_CACHE_LIFE = 1000 * 60 * 5;
+
+    public static final Pattern OPTIONS_PATTERN
+            = Pattern.compile(Pattern.quote("{options[") + "(.+)" + Pattern.quote("]}"));
+
+    private static final Logger LOG = LoggerFactory.getLogger(OptionsRenderer.class);
+
+    private final ApplicationContext applicationContext;
+    private final Renderer renderer;
+
+    public OptionsRenderer(final ApplicationContext applicationContext, final Renderer renderer) {
+        this.applicationContext = applicationContext;
+        this.renderer = renderer;
+    }
+
+    @Override
+    public boolean isRenderable(final String path, final Request request) {
+        return renderer.isRenderable(path, request);
+    }
+
+    @Override
+    public void render(final String path, final Request request) throws IOException {
+
+        Matcher matcher =  OPTIONS_PATTERN.matcher((String) path);
+
+        if (null != matcher && matcher.find()) {
+            boolean done = false;
+            String match = matcher.group(1);
+            ListAttribute fallbacks = (ListAttribute) TilesAccess
+                    .getCurrentContainer(request)
+                    .getAttributeContext(request)
+                    .getAttribute(match);
+
+            if (null == fallbacks) {
+                throw new IllegalStateException("A matching list-attribute name=\"" + match + "\" must be defined.");
+            } else if (fallbacks.getValue().isEmpty()) {
+                throw new IllegalStateException(
+                        "list-attribute name=\"" + match + "\" must have minimum one attribute");
+            }
+
+            for (Attribute option : (List<Attribute>) fallbacks.getValue()) {
+                String template = path.replaceFirst(Pattern.quote(matcher.group()), (String) option.getValue());
+                done = renderAttempt(template, request);
+                if (done) { break; }
+            }
+            if (!done) {
+                throw new IOException("None of the options existed for " + path);
+            }
+        } else {
+            renderer.render(path, request);
+        }
+    }
+
+    private boolean renderAttempt(final String template, final Request request) throws IOException {
+        boolean result = false;
+        if (Cache.attemptTemplate(template)) {
+            try {
+                if (null != applicationContext.getResource(template)) {
+                    renderer.render(template, request);
+                    result = true;
+                }
+            } catch (IOException ex) {
+                if (ex.getMessage().contains(template)) {
+                    // expected outcome. continue loop.
+                    LOG.trace(ex.getMessage());
+                } else {
+                    // comes from an inner templateAttribute.render(..) so throw on
+                    throw ex;
+                }
+            } catch (RuntimeException ex) {
+                if (ex.getMessage().contains(template)) {
+                    // expected outcome. continue loop.
+                    LOG.trace(ex.getMessage());
+                } else {
+                    // comes from an inner templateAttribute.render(..) so throw on
+                    throw ex;
+                }
+            }
+            Cache.update(template, result);
+        }
+        return result;
+    }
+
+    private static final class Cache {
+
+        private static final long CACHE_LIFE = Long.getLong(CACHE_LIFE_PROPERTY, DEFAULT_CACHE_LIFE);
+
+        /** It takes CACHE_LIFE milliseconds for any hot deployments to register.
+         */
+        private static final ConcurrentMap<String,Boolean> TEMPLATE_EXISTS;
+
+        static {
+            LOG.info("cache_ttl_ms=" + CACHE_LIFE);
+
+            LoadingCache<String,Boolean> builder = CacheBuilder
+                    .newBuilder()
+                    .expireAfterWrite(CACHE_LIFE, TimeUnit.MILLISECONDS)
+                    .build(
+                        new CacheLoader<String, Boolean>() {
+                            @Override
+                            public Boolean load(String key) {
+                                throw new UnsupportedOperationException(
+                                        "illegal TEMPLATE_EXISTS.get(\"" + key
+                                        + "\") before TEMPLATE_EXISTS.containsKey(\"" + key + "\")");
+                            }
+                        });
+
+            TEMPLATE_EXISTS = builder.asMap();
+        }
+
+
+        static boolean attemptTemplate(final String template) {
+            Boolean found = TEMPLATE_EXISTS.get(template);
+            return found == null || found;
+        }
+
+        static void update(final String template, final boolean found) {
+            TEMPLATE_EXISTS.putIfAbsent(template, found);
+        }
+
+        private Cache() {}
+    }
+}
diff --git a/Java-base/tiles/src/tiles-extras/src/main/java/org/apache/tiles/extras/renderer/package-info.java b/Java-base/tiles/src/tiles-extras/src/main/java/org/apache/tiles/extras/renderer/package-info.java
new file mode 100644
index 000000000..f41d8f61f
--- /dev/null
+++ b/Java-base/tiles/src/tiles-extras/src/main/java/org/apache/tiles/extras/renderer/package-info.java
@@ -0,0 +1,27 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * Provides a custom "options" syntax for attributes.
+ * The first option from a list that can be rendered is.
+ *
+ * Comes from <a href="http://tech.finn.no/the-ultimate-view/">The Ultimate View</a> article.
+ */
+package org.apache.tiles.extras.renderer;
diff --git a/Java-base/tiles/src/tiles-extras/src/main/resources/LICENSE.txt b/Java-base/tiles/src/tiles-extras/src/main/resources/LICENSE.txt
new file mode 100644
index 000000000..d64569567
--- /dev/null
+++ b/Java-base/tiles/src/tiles-extras/src/main/resources/LICENSE.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/Java-base/tiles/src/tiles-extras/src/main/resources/NOTICE.txt b/Java-base/tiles/src/tiles-extras/src/main/resources/NOTICE.txt
new file mode 100644
index 000000000..1f13ff856
--- /dev/null
+++ b/Java-base/tiles/src/tiles-extras/src/main/resources/NOTICE.txt
@@ -0,0 +1,6 @@
+   Apache Tiles
+   Copyright 1999-2009 The Apache Software Foundation
+
+   This product includes software developed at
+   The Apache Software Foundation (http://www.apache.org/).
+
diff --git a/Java-base/tiles/src/tiles-extras/src/site/site.xml b/Java-base/tiles/src/tiles-extras/src/site/site.xml
new file mode 100644
index 000000000..475789550
--- /dev/null
+++ b/Java-base/tiles/src/tiles-extras/src/site/site.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<project name="Apache Tiles - Extras">
+     <skin>
+        <groupId>org.apache.maven.skins</groupId>
+        <artifactId>maven-fluido-skin</artifactId>
+        <version>1.3.0</version>
+     </skin>
+     <custom>
+        <fluidoSkin>
+        <topBarEnabled>true</topBarEnabled>
+        <sideBarEnabled>false</sideBarEnabled>
+        <searchEnabled>true</searchEnabled>
+        <gitHub>
+            <projectId>apache/tiles</projectId>
+            <ribbonOrientation>right</ribbonOrientation>
+            <ribbonColor>darkblue</ribbonColor>
+        </gitHub>
+        </fluidoSkin>
+     </custom>
+    <bannerLeft>
+        <name>Apache Tiles&#8482;</name>
+        <src>http://tiles.apache.org/images/logo.png</src>
+        <href>http://tiles.apache.org</href>
+    </bannerLeft>
+    <bannerRight>
+        <name>Apache Software Foundation</name>
+        <src>http://struts.apache.org/images/asf-logo.gif</src>
+        <href>http://www.apache.org</href>
+    </bannerRight>
+    <body>
+
+        <menu name="Apache Tiles&#8482;">
+            <item
+                   name="Welcome"
+                   href="../../index.html"/>
+            <item
+                    name="Tiles 3.0.x"
+                    href="../../framework/index.html"/>
+            <item
+                    name="Autotag 1.0.x"
+                    href="../../tiles-autotag/index.html"/>
+            <item
+                    name="Request 1.0.x"
+                    href="../../tiles-request/index.html"/>
+            <item
+                   name="Security bulletins"
+                   href="../security/index.html"/>
+            <item
+                   name="Download"
+                   href="http://tiles.apache.org/download.html"/>
+        </menu>
+
+        <menu ref="modules" />
+        <menu ref="reports" />
+
+        <footer>
+            <div class="row span12">
+                Apache Tiles, Tiles, Apache, the Apache feather logo, and the Apache Tiles
+                project logos are trademarks of The Apache Software Foundation.
+            </div>
+        </footer>
+    </body>
+</project>
diff --git a/Java-base/tiles/src/tiles-extras/src/test/java/org/apache/tiles/extras/complete/CompleteAutoloadTilesContainerFactoryTest.java b/Java-base/tiles/src/tiles-extras/src/test/java/org/apache/tiles/extras/complete/CompleteAutoloadTilesContainerFactoryTest.java
new file mode 100644
index 000000000..b03a51702
--- /dev/null
+++ b/Java-base/tiles/src/tiles-extras/src/test/java/org/apache/tiles/extras/complete/CompleteAutoloadTilesContainerFactoryTest.java
@@ -0,0 +1,333 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.extras.complete;
+
+import static org.easymock.EasyMock.*;
+import static org.easymock.classextension.EasyMock.*;
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import javax.el.ExpressionFactory;
+import javax.servlet.ServletContext;
+import javax.servlet.jsp.JspApplicationContext;
+import javax.servlet.jsp.JspFactory;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.Definition;
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.compat.definition.digester.CompatibilityDigesterDefinitionsReader;
+import org.apache.tiles.definition.pattern.PatternDefinitionResolver;
+import org.apache.tiles.definition.pattern.PrefixedPatternDefinitionResolver;
+import org.apache.tiles.evaluator.AttributeEvaluatorFactory;
+import org.apache.tiles.evaluator.BasicAttributeEvaluatorFactory;
+import org.apache.tiles.impl.mgmt.CachingTilesContainer;
+import org.apache.tiles.locale.LocaleResolver;
+import org.apache.tiles.renderer.DefinitionRenderer;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.ApplicationResource;
+import org.apache.tiles.request.freemarker.render.FreemarkerRenderer;
+import org.apache.tiles.request.mustache.MustacheRenderer;
+import org.apache.tiles.request.render.BasicRendererFactory;
+import org.apache.tiles.request.render.ChainedDelegateRenderer;
+import org.apache.tiles.request.render.DispatchRenderer;
+import org.apache.tiles.request.render.Renderer;
+import org.apache.tiles.request.render.StringRenderer;
+import org.apache.tiles.request.servlet.ServletApplicationContext;
+import org.apache.tiles.request.velocity.render.VelocityRenderer;
+import org.apache.velocity.tools.view.VelocityView;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests {@link CompleteAutoloadTilesContainerFactory}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class CompleteAutoloadTilesContainerFactoryTest {
+
+    /**
+     * The object to test.
+     */
+    private CompleteAutoloadTilesContainerFactory factory;
+
+    /**
+     * Initializes the object.
+     */
+    @Before
+    public void setUp() {
+        factory = new CompleteAutoloadTilesContainerFactory();
+    }
+
+    /**
+     * Test method for
+     * {@link CompleteAutoloadTilesContainerFactory#createDecoratedContainer(TilesContainer, ApplicationContext)
+     * .
+     */
+    @Test
+    public void testCreateDecoratedContainer() {
+        ApplicationContext applicationContext = createMock(ServletApplicationContext.class);
+        TilesContainer wrapped = createMock(TilesContainer.class);
+
+        replay(applicationContext, wrapped);
+        assertSame(wrapped,
+                ((CachingTilesContainer) factory.createDecoratedContainer(wrapped, applicationContext))
+                        .getWrappedContainer());
+        verify(applicationContext, wrapped);
+    }
+
+    /**
+     * Test method for
+     * {@link CompleteAutoloadTilesContainerFactory
+     * #registerAttributeRenderers(BasicRendererFactory, ApplicationContext,
+     * TilesContainer, evaluator.AttributeEvaluatorFactory)}
+     * .
+     */
+    @SuppressWarnings("deprecation")
+    @Test
+    public void testRegisterAttributeRenderers() {
+        BasicRendererFactory rendererFactory = createMock(BasicRendererFactory.class);
+        ServletApplicationContext applicationContext = createMock(ServletApplicationContext.class);
+        TilesContainer container = createMock(TilesContainer.class);
+        AttributeEvaluatorFactory attributeEvaluatorFactory = createMock(AttributeEvaluatorFactory.class);
+        ServletContext servletContext = createMock(ServletContext.class);
+
+        rendererFactory.registerRenderer(eq("string"), isA(StringRenderer.class));
+        rendererFactory.registerRenderer(eq("template"), isA(DispatchRenderer.class));
+        rendererFactory.registerRenderer(eq("definition"), isA(DefinitionRenderer.class));
+        rendererFactory.registerRenderer(eq("freemarker"), isA(FreemarkerRenderer.class));
+        rendererFactory.registerRenderer(eq("velocity"), isA(VelocityRenderer.class));
+        rendererFactory.registerRenderer(eq("mustache"), isA(MustacheRenderer.class));
+
+        expect(applicationContext.getContext()).andReturn(servletContext).anyTimes();
+        expect(servletContext.getInitParameter(VelocityView.PROPERTIES_KEY)).andReturn(null);
+        expect(servletContext.getInitParameter(VelocityView.TOOLS_KEY)).andReturn(null);
+        expect(servletContext.getAttribute(VelocityView.TOOLS_KEY)).andReturn(null);
+        expect(servletContext.getResourceAsStream("/WEB-INF/velocity.properties")).andReturn(
+                getClass().getResourceAsStream("/velocity.properties"));
+        expect(servletContext.getResourceAsStream("/WEB-INF/VM_global_library.vm")).andReturn(
+                getClass().getResourceAsStream("/VM_global_library.vm"));
+        expect(servletContext.getResourceAsStream("/WEB-INF/tools.xml")).andReturn(
+                getClass().getResourceAsStream("/tools.xml"));
+        expect(servletContext.getResourceAsStream(VelocityView.DEPRECATED_USER_TOOLS_PATH)).andReturn(null);
+        servletContext.log((String) anyObject());
+        expectLastCall().anyTimes();
+        expect(servletContext.getRealPath("/")).andReturn(null);
+
+        replay(rendererFactory, applicationContext, container, attributeEvaluatorFactory, servletContext);
+        factory.registerAttributeRenderers(rendererFactory, applicationContext, container, attributeEvaluatorFactory);
+        verify(rendererFactory, applicationContext, container, attributeEvaluatorFactory, servletContext);
+    }
+
+    /**
+     * Tests
+     * {@link CompleteAutoloadTilesContainerFactory#createDefaultAttributeRenderer(BasicRendererFactory,
+     * ApplicationContext, TilesContainer, AttributeEvaluatorFactory)}.
+     */
+    @Test
+    public void testCreateDefaultAttributeRenderer() {
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        TilesContainer container = createMock(TilesContainer.class);
+        AttributeEvaluatorFactory attributeEvaluatorFactory = createMock(AttributeEvaluatorFactory.class);
+        BasicRendererFactory rendererFactory = createMock(BasicRendererFactory.class);
+        Renderer stringRenderer = createMock(Renderer.class);
+        Renderer templateRenderer = createMock(Renderer.class);
+        Renderer definitionRenderer = createMock(Renderer.class);
+        Renderer velocityRenderer = createMock(Renderer.class);
+        Renderer freemarkerRenderer = createMock(Renderer.class);
+        Renderer mustacheRenderer = createMock(Renderer.class);
+
+        expect(rendererFactory.getRenderer("string")).andReturn(stringRenderer);
+        expect(rendererFactory.getRenderer("template")).andReturn(templateRenderer);
+        expect(rendererFactory.getRenderer("definition")).andReturn(definitionRenderer);
+        expect(rendererFactory.getRenderer("velocity")).andReturn(velocityRenderer);
+        expect(rendererFactory.getRenderer("freemarker")).andReturn(freemarkerRenderer);
+        expect(rendererFactory.getRenderer("mustache")).andReturn(mustacheRenderer);
+
+        replay(container, attributeEvaluatorFactory, rendererFactory, applicationContext);
+        Renderer renderer = factory.createDefaultAttributeRenderer(rendererFactory, applicationContext, container,
+                attributeEvaluatorFactory);
+        assertTrue("The default renderer class is not correct", renderer instanceof ChainedDelegateRenderer);
+        verify(container, attributeEvaluatorFactory, rendererFactory, applicationContext);
+    }
+
+    /**
+     * Test method for
+     * {@link CompleteAutoloadTilesContainerFactory
+     * #createAttributeEvaluatorFactory(ApplicationContext, locale.LocaleResolver)}
+     * .
+     */
+    @Test
+    public void testCreateAttributeEvaluatorFactory() {
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        LocaleResolver resolver = createMock(LocaleResolver.class);
+        ServletContext servletContext = createMock(ServletContext.class);
+        JspFactory jspFactory = createMock(JspFactory.class);
+        JspApplicationContext jspApplicationContext = createMock(JspApplicationContext.class);
+        ExpressionFactory expressionFactory = createMock(ExpressionFactory.class);
+
+        expect(applicationContext.getContext()).andReturn(servletContext);
+        expect(jspFactory.getJspApplicationContext(servletContext)).andReturn(jspApplicationContext);
+        expect(jspApplicationContext.getExpressionFactory()).andReturn(expressionFactory);
+
+        replay(applicationContext, resolver, servletContext, jspFactory, jspApplicationContext, expressionFactory);
+        JspFactory.setDefaultFactory(jspFactory);
+        AttributeEvaluatorFactory attributeEvaluatorFactory = factory.createAttributeEvaluatorFactory(
+                applicationContext, resolver);
+        assertTrue(attributeEvaluatorFactory instanceof BasicAttributeEvaluatorFactory);
+        assertNotNull(attributeEvaluatorFactory.getAttributeEvaluator("EL"));
+        assertNotNull(attributeEvaluatorFactory.getAttributeEvaluator("MVEL"));
+        assertNotNull(attributeEvaluatorFactory.getAttributeEvaluator("OGNL"));
+        verify(applicationContext, resolver, servletContext, jspFactory, jspApplicationContext, expressionFactory);
+    }
+
+    /**
+     * Test method for
+     * {@link CompleteAutoloadTilesContainerFactory#createPatternDefinitionResolver(Class)}
+     * .
+     */
+    @Test
+    public void testCreatePatternDefinitionResolver() {
+        PatternDefinitionResolver<Integer> resolver = factory.createPatternDefinitionResolver(Integer.class);
+        assertTrue(resolver instanceof PrefixedPatternDefinitionResolver);
+        Definition definitionWildcard = new Definition("WILDCARD:blah*", (Attribute) null, null);
+        Definition definitionRegexp = new Definition("REGEXP:what(.*)", (Attribute) null, null);
+        Map<String, Definition> definitionMap = new HashMap<String, Definition>();
+        definitionMap.put("WILDCARD:blah*", definitionWildcard);
+        definitionMap.put("REGEXP:what(.*)", definitionRegexp);
+        resolver.storeDefinitionPatterns(definitionMap, 1);
+        Definition result = resolver.resolveDefinition("blahX", 1);
+        assertEquals("blahX", result.getName());
+        result = resolver.resolveDefinition("whatX", 1);
+        assertEquals("whatX", result.getName());
+    }
+
+    /**
+     * Test method for
+     * {@link CompleteAutoloadTilesContainerFactory#getSources(ApplicationContext)}
+     * .
+     * @throws IOException If something goes wrong.
+     */
+    @Test
+    public void testGetSources() throws IOException {
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+
+        ApplicationResource resource1 = createMock(ApplicationResource.class);
+        expect(resource1.getLocale()).andReturn(Locale.ROOT);
+        ApplicationResource resource2 = createMock(ApplicationResource.class);
+        expect(resource2.getLocale()).andReturn(Locale.ITALY);
+        ApplicationResource resource3 = createMock(ApplicationResource.class);
+        expect(resource3.getLocale()).andReturn(Locale.ROOT);
+
+        Collection<ApplicationResource> resourceSet1 = new HashSet<ApplicationResource>();
+        resourceSet1.add(resource1);
+        resourceSet1.add(resource2);
+
+        Collection<ApplicationResource> resourceSet2 = new HashSet<ApplicationResource>();
+        resourceSet2.add(resource3);
+
+        expect(applicationContext.getResources("/WEB-INF/**/tiles*.xml")).andReturn(resourceSet1);
+        expect(applicationContext.getResources("classpath*:META-INF/**/tiles*.xml")).andReturn(resourceSet2);
+
+        replay(applicationContext, resource1, resource2, resource3);
+        List<ApplicationResource> urls = factory.getSources(applicationContext);
+        assertEquals(2, urls.size());
+        assertTrue(urls.contains(resource1));
+        assertTrue(urls.contains(resource3));
+        verify(applicationContext, resource1, resource2, resource3);
+    }
+
+    /**
+     * Regression test for TILES-484 issue.
+     *
+     * @throws IOException If something goes wrong.
+     */
+    @Test
+    public void testTILES484first() throws IOException {
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+
+        ApplicationResource resource = createMock(ApplicationResource.class);
+        expect(resource.getLocale()).andReturn(Locale.ROOT);
+
+        Collection<ApplicationResource> resourceSet = new HashSet<ApplicationResource>();
+        resourceSet.add(resource);
+
+        expect(applicationContext.getResources("/WEB-INF/**/tiles*.xml")).andReturn(null);
+        expect(applicationContext.getResources("classpath*:META-INF/**/tiles*.xml")).andReturn(resourceSet);
+
+        replay(applicationContext, resource);
+        List<ApplicationResource> resources = factory.getSources(applicationContext);
+        assertEquals(1, resources.size());
+        assertTrue(resources.contains(resource));
+        verify(applicationContext, resource);
+    }
+
+    /**
+     * Regression test for TILES-484 issue.
+     *
+     * @throws IOException If something goes wrong.
+     */
+    @Test
+    public void testTILES484second() throws IOException {
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+
+        ApplicationResource resource1 = createMock(ApplicationResource.class);
+        expect(resource1.getLocale()).andReturn(Locale.ROOT);
+        ApplicationResource resource2 = createMock(ApplicationResource.class);
+        expect(resource2.getLocale()).andReturn(Locale.ITALY);
+
+        Collection<ApplicationResource> resourceSet = new HashSet<ApplicationResource>();
+        resourceSet.add(resource1);
+        resourceSet.add(resource2);
+
+        expect(applicationContext.getResources("/WEB-INF/**/tiles*.xml")).andReturn(resourceSet);
+        expect(applicationContext.getResources("classpath*:META-INF/**/tiles*.xml")).andReturn(null);
+
+        replay(applicationContext, resource1, resource2);
+        List<ApplicationResource> resources = factory.getSources(applicationContext);
+        assertEquals(1, resources.size());
+        assertTrue(resources.contains(resource1));
+        verify(applicationContext, resource1, resource2);
+    }
+
+    /**
+     * Test method for
+     * {@link CompleteAutoloadTilesContainerFactory
+     * #createDefinitionsReader(ApplicationContext)}
+     * .
+     */
+    @Test
+    public void testCreateDefinitionsReader() {
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+
+        replay(applicationContext);
+        assertTrue(factory.createDefinitionsReader(applicationContext) instanceof CompatibilityDigesterDefinitionsReader);
+        verify(applicationContext);
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-extras/src/test/java/org/apache/tiles/extras/complete/CompleteAutoloadTilesInitializerTest.java b/Java-base/tiles/src/tiles-extras/src/test/java/org/apache/tiles/extras/complete/CompleteAutoloadTilesInitializerTest.java
new file mode 100644
index 000000000..a09566a7d
--- /dev/null
+++ b/Java-base/tiles/src/tiles-extras/src/test/java/org/apache/tiles/extras/complete/CompleteAutoloadTilesInitializerTest.java
@@ -0,0 +1,81 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.extras.complete;
+
+import static org.junit.Assert.*;
+import static org.easymock.EasyMock.*;
+
+import javax.servlet.ServletContext;
+
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.servlet.wildcard.WildcardServletApplicationContext;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * @author antonio
+ *
+ * @version $Rev$ $Date$
+ */
+public class CompleteAutoloadTilesInitializerTest {
+
+    /**
+     * The object to test.
+     */
+    private CompleteAutoloadTilesInitializer initializer;
+
+    /**
+     * Sets up the object to test.
+     */
+    @Before
+    public void setUp() {
+        initializer = new CompleteAutoloadTilesInitializer();
+    }
+
+    /**
+     * Test method for {@link CompleteAutoloadTilesInitializer#createTilesApplicationContext(ApplicationContext)}.
+     */
+    @Test
+    public void testCreateTilesApplicationContext() {
+        ApplicationContext preliminaryContext = createMock(ApplicationContext.class);
+        ServletContext servletContext = createMock(ServletContext.class);
+
+        expect(preliminaryContext.getContext()).andReturn(servletContext);
+
+        replay(preliminaryContext, servletContext);
+        assertTrue(initializer
+                .createTilesApplicationContext(preliminaryContext) instanceof WildcardServletApplicationContext);
+        verify(preliminaryContext, servletContext);
+    }
+
+    /**
+     * Test method for {@link CompleteAutoloadTilesInitializer#createContainerFactory(ApplicationContext)}.
+     */
+    @Test
+    public void testCreateContainerFactory() {
+        ApplicationContext context = createMock(ApplicationContext.class);
+
+        replay(context);
+        assertTrue(initializer.createContainerFactory(context) instanceof CompleteAutoloadTilesContainerFactory);
+        verify(context);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-extras/src/test/java/org/apache/tiles/extras/complete/CompleteAutoloadTilesListenerTest.java b/Java-base/tiles/src/tiles-extras/src/test/java/org/apache/tiles/extras/complete/CompleteAutoloadTilesListenerTest.java
new file mode 100644
index 000000000..83f77e7bb
--- /dev/null
+++ b/Java-base/tiles/src/tiles-extras/src/test/java/org/apache/tiles/extras/complete/CompleteAutoloadTilesListenerTest.java
@@ -0,0 +1,45 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.extras.complete;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+/**
+ * Tests {@link CompleteAutoloadTilesListener}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class CompleteAutoloadTilesListenerTest {
+
+    /**
+     * Test method for
+     * {@link org.apache.tiles.extras.complete.CompleteAutoloadTilesListener#createTilesInitializer()}
+     * .
+     */
+    @Test
+    public void testCreateTilesInitializer() {
+        CompleteAutoloadTilesListener listener = new CompleteAutoloadTilesListener();
+        assertTrue(listener.createTilesInitializer() instanceof CompleteAutoloadTilesInitializer);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-extras/src/test/java/org/apache/tiles/extras/module/ModularTilesInitializerTest.java b/Java-base/tiles/src/tiles-extras/src/test/java/org/apache/tiles/extras/module/ModularTilesInitializerTest.java
new file mode 100644
index 000000000..a03b5318a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-extras/src/test/java/org/apache/tiles/extras/module/ModularTilesInitializerTest.java
@@ -0,0 +1,124 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.extras.module;
+
+import static org.junit.Assert.*;
+import static org.easymock.EasyMock.*;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import javax.servlet.ServletContext;
+
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.startup.TilesInitializer;
+import org.junit.Test;
+
+/**
+ * Tests {@link ModularTilesInitializer}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ModularTilesInitializerTest {
+
+    /**
+     * Tests {@link ModularTilesInitializer#initialize(ApplicationContext)}
+     * and {@link ModularTilesInitializer#destroy()}.
+     *
+     * @throws MalformedURLException Never thrown.
+     */
+    @Test
+    public void testInitialize() throws MalformedURLException {
+        ApplicationContext preliminaryContext = createMock(ApplicationContext.class);
+        ServletContext servletContext = createMock(ServletContext.class);
+        URL manifestUrl = getClass().getResource("/FAKE-MANIFEST.MF");
+
+        expect(preliminaryContext.getContext()).andReturn(servletContext);
+        expect(servletContext.getResource("/META-INF/MANIFEST.MF")).andReturn(manifestUrl);
+
+        replay(preliminaryContext, servletContext);
+        ModularTilesInitializer initializer = new ModularTilesInitializer();
+        initializer.initialize(preliminaryContext);
+        assertTrue(TilesInitializer1.initialized);
+        assertTrue(TilesInitializer2.initialized);
+        initializer.destroy();
+        assertTrue(TilesInitializer1.destroyed);
+        assertTrue(TilesInitializer2.destroyed);
+        verify(preliminaryContext, servletContext);
+    }
+
+    /**
+     * A mock {@link TilesInitializer} with probes.
+     *
+     * @version $Rev$ $Date$
+     */
+    public static class TilesInitializer1 implements TilesInitializer {
+
+        /**
+         * A probe to see if the initializer has been initialized.
+         */
+        private static boolean initialized = false;
+
+        /**
+         * A probe to see if the initializer has been destroyed.
+         */
+        private static boolean destroyed = false;
+
+        /** {@inheritDoc} */
+        public void initialize(ApplicationContext preliminaryContext) {
+            initialized = true;
+        }
+
+        /** {@inheritDoc} */
+        public void destroy() {
+            destroyed = true;
+        }
+    }
+
+    /**
+     * A second mock {@link TilesInitializer} with probes.
+     *
+     * @version $Rev$ $Date$
+     */
+    public static class TilesInitializer2 implements TilesInitializer {
+
+        /**
+         * A probe to see if the initializer has been initialized.
+         */
+        private static boolean initialized = false;
+
+        /**
+         * A probe to see if the initializer has been destroyed.
+         */
+        private static boolean destroyed = false;
+
+        /** {@inheritDoc} */
+        public void initialize(ApplicationContext preliminaryContext) {
+            initialized = true;
+        }
+
+        /** {@inheritDoc} */
+        public void destroy() {
+            destroyed = true;
+        }
+    }
+}
diff --git a/Java-base/tiles/src/tiles-extras/src/test/java/org/apache/tiles/extras/module/ModularTilesListenerTest.java b/Java-base/tiles/src/tiles-extras/src/test/java/org/apache/tiles/extras/module/ModularTilesListenerTest.java
new file mode 100644
index 000000000..b02a9d6b7
--- /dev/null
+++ b/Java-base/tiles/src/tiles-extras/src/test/java/org/apache/tiles/extras/module/ModularTilesListenerTest.java
@@ -0,0 +1,45 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.extras.module;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+/**
+ * Tests {@link ModularTilesListener}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ModularTilesListenerTest {
+
+    /**
+     * Test method for
+     * {@link org.apache.tiles.extras.complete.ModularTilesListener#createTilesInitializer()}
+     * .
+     */
+    @Test
+    public void testCreateTilesInitializer() {
+        ModularTilesListener listener = new ModularTilesListener();
+        assertTrue(listener.createTilesInitializer() instanceof ModularTilesInitializer);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-extras/src/test/java/org/apache/tiles/extras/renderer/OptionsRendererTest.java b/Java-base/tiles/src/tiles-extras/src/test/java/org/apache/tiles/extras/renderer/OptionsRendererTest.java
new file mode 100644
index 000000000..765aa711b
--- /dev/null
+++ b/Java-base/tiles/src/tiles-extras/src/test/java/org/apache/tiles/extras/renderer/OptionsRendererTest.java
@@ -0,0 +1,139 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.extras.renderer;
+
+import static org.easymock.EasyMock.*;
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import org.apache.tiles.Attribute;
+import org.apache.tiles.ListAttribute;
+import org.apache.tiles.access.TilesAccess;
+import org.apache.tiles.impl.BasicTilesContainer;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.ApplicationResource;
+
+import org.apache.tiles.request.Request;
+import org.apache.tiles.request.locale.PostfixedApplicationResource;
+import org.apache.tiles.request.render.StringRenderer;
+import org.junit.Test;
+
+/**
+ * Tests {@link OptionsRenderer}.
+ *
+ * @version $Rev$ $Date$
+ */
+public final class OptionsRendererTest {
+
+    private final BasicTilesContainer container = new BasicTilesContainer();
+
+    private final Map<String, Object> appScope = new HashMap<String, Object>(){{
+        put(TilesAccess.CONTAINER_ATTRIBUTE, container);
+    }};
+
+    private final Map<String, Object> requestScope = new HashMap<String, Object>();
+
+    private final ApplicationResource template = new PostfixedApplicationResource("Result"){
+        @Override
+        public InputStream getInputStream() throws IOException {
+            throw new AssertionError("Shouldn't be called.");
+        }
+        @Override
+        public long getLastModified() throws IOException {
+            return 0;
+        }
+    };
+
+    private final ApplicationContext context = new ApplicationContext(){
+        @Override
+        public Object getContext() {
+            throw new AssertionError("Shouldn't be called.");
+        }
+        @Override
+        public Map<String, Object> getApplicationScope() {
+            return appScope;
+        }
+        @Override
+        public Map<String, String> getInitParams() {
+            throw new AssertionError("Shouldn't be called.");
+        }
+        @Override
+        public ApplicationResource getResource(String string) {
+            return template;
+        }
+        @Override
+        public ApplicationResource getResource(ApplicationResource ar, Locale locale) {
+            throw new AssertionError("Shouldn't be called.");
+        }
+        @Override
+        public Collection<ApplicationResource> getResources(String string) {
+            throw new AssertionError("Shouldn't be called.");
+        }
+    };
+
+    /**
+     * Tests
+     * {@link OptionsRenderer#render(String, Request)}.
+     *
+     * @throws IOException If something goes wrong during rendition.
+     */
+    @Test
+    public void testWrite() throws IOException {
+        StringWriter writer = new StringWriter();
+        Request request = createMock(Request.class);
+
+        requestScope.put(TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME, container);
+
+        expect(request.getContext(matches("request"))).andReturn(requestScope).anyTimes();
+        expect(request.getApplicationContext()).andReturn(context);
+        expect(request.getWriter()).andReturn(writer);
+        replay(request);
+
+        container
+                .getAttributeContext(request)
+                .putAttribute("test-fallback", new ListAttribute(){{
+                    add(new Attribute("Result"));
+                }});
+
+        OptionsRenderer renderer = new OptionsRenderer(context, new StringRenderer());
+        renderer.render("{options[test-fallback]}", request);
+        writer.close();
+        assertEquals("Not written 'Result'", "Result", writer.toString());
+        verify(request);
+    }
+
+    /**
+     * Tests
+     * {@link OptionsRenderer#isRenderable(String, Request)}.
+     */
+    @Test
+    public void testIsRenderable() {
+        Request requestContext = createMock(Request.class);
+        OptionsRenderer renderer = new OptionsRenderer(context, new StringRenderer());
+        assertTrue(renderer.isRenderable("any-string", requestContext));
+    }
+}
diff --git a/Java-base/tiles/src/tiles-extras/src/test/resources/FAKE-MANIFEST.MF b/Java-base/tiles/src/tiles-extras/src/test/resources/FAKE-MANIFEST.MF
new file mode 100644
index 000000000..352b0db55
--- /dev/null
+++ b/Java-base/tiles/src/tiles-extras/src/test/resources/FAKE-MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Tiles-Initializer: org.apache.tiles.extras.module.ModularTilesInitializerTest$TilesInitializer2
+
diff --git a/Java-base/tiles/src/tiles-extras/src/test/resources/META-INF/MANIFEST.MF b/Java-base/tiles/src/tiles-extras/src/test/resources/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..540b9880c
--- /dev/null
+++ b/Java-base/tiles/src/tiles-extras/src/test/resources/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Tiles-Initializer: org.apache.tiles.extras.module.ModularTilesInitializerTest$TilesInitializer1
+
diff --git a/Java-base/tiles/src/tiles-extras/src/test/resources/VM_global_library.vm b/Java-base/tiles/src/tiles-extras/src/test/resources/VM_global_library.vm
new file mode 100644
index 000000000..7e8277de0
--- /dev/null
+++ b/Java-base/tiles/src/tiles-extras/src/test/resources/VM_global_library.vm
@@ -0,0 +1,60 @@
+## 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.
+
+## Display all queued Struts errors
+#macro (errorMarkup)
+    #if ($errors.exist() )
+        <ul>
+        #foreach ($e in $errors.all )
+            $e
+        #end
+        </ul>
+    #end
+#end
+
+## Display all queued Struts errors for a particular property
+#macro (errorMarkupForProperty $property)
+    #if ($errors.exist($property) )
+        <ul>
+        #foreach ($er in $errors.get($property))
+            $er
+        #end
+        </ul>
+    #end
+#end
+
+## Display all queued Struts errors
+#macro (messageMarkup)
+    #if ($messages.exist() )
+        <ul>
+        #foreach ($m in $messages.all )
+            $m
+        #end
+        </ul>
+    #end
+#end
+
+## Display all queued Struts action messages for a particular property
+#macro (messageMarkupForProperty $property)
+    #if ($messages.exist($property) )
+        <ul>
+        #foreach ($m in $messages.get($property))
+            $m
+        #end
+        </ul>
+    #end
+#end
diff --git a/Java-base/tiles/src/tiles-extras/src/test/resources/tools.xml b/Java-base/tiles/src/tiles-extras/src/test/resources/tools.xml
new file mode 100644
index 000000000..ae29eb6d7
--- /dev/null
+++ b/Java-base/tiles/src/tiles-extras/src/test/resources/tools.xml
@@ -0,0 +1,27 @@
+<?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.
+-->
+<tools>
+  <toolbox scope="request">
+    <tool class="org.apache.velocity.tools.generic.ContextTool"/>
+  </toolbox>
+  <toolbox scope="application">
+     <tool class="org.apache.velocity.tools.generic.EscapeTool"/>
+   </toolbox>
+</tools>
diff --git a/Java-base/tiles/src/tiles-extras/src/test/resources/velocity.properties b/Java-base/tiles/src/tiles-extras/src/test/resources/velocity.properties
new file mode 100644
index 000000000..4dbb19490
--- /dev/null
+++ b/Java-base/tiles/src/tiles-extras/src/test/resources/velocity.properties
@@ -0,0 +1,114 @@
+# 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.
+
+# ----------------------------------------------------------------------------
+# These are the default properties for the
+# Velocity Runtime. These values are used when
+# Runtime.init() is called, and when Runtime.init(properties)
+# fails to find the specificed properties file.
+# ----------------------------------------------------------------------------
+
+
+# ----------------------------------------------------------------------------
+# R U N T I M E  L O G
+# ----------------------------------------------------------------------------
+# Velocity uses the Servlet APIs logging facilites.
+
+# ----------------------------------------------------------------------------
+# This controls if Runtime.error(), info() and warn() messages include the
+# whole stack trace. The last property controls whether invalid references
+# are logged.
+# ----------------------------------------------------------------------------
+
+runtime.log.invalid.reference = true
+
+
+# ----------------------------------------------------------------------------
+# T E M P L A T E  E N C O D I N G
+# ----------------------------------------------------------------------------
+
+input.encoding=ISO-8859-1
+output.encoding=ISO-8859-1
+
+
+# ----------------------------------------------------------------------------
+# F O R E A C H  P R O P E R T I E S
+# ----------------------------------------------------------------------------
+# These properties control how the counter is accessed in the #foreach
+# directive. By default the reference $velocityCount will be available
+# in the body of the #foreach directive. The default starting value
+# for this reference is 1.
+# ----------------------------------------------------------------------------
+
+directive.foreach.counter.name = velocityCount
+directive.foreach.counter.initial.value = 1
+
+
+# ----------------------------------------------------------------------------
+# I N C L U D E  P R O P E R T I E S
+# ----------------------------------------------------------------------------
+# These are the properties that governed the way #include'd content
+# is governed.
+# ----------------------------------------------------------------------------
+
+directive.include.output.errormsg.start = <!-- include error :
+directive.include.output.errormsg.end   =  see error log -->
+
+
+# ----------------------------------------------------------------------------
+# P A R S E  P R O P E R T I E S
+# ----------------------------------------------------------------------------
+
+directive.parse.max.depth = 10
+
+
+# ----------------------------------------------------------------------------
+# VELOCIMACRO PROPERTIES
+# ----------------------------------------------------------------------------
+# global : name of default global library.  It is expected to be in the regular
+# template path.  You may remove it (either the file or this property) if
+# you wish with no harm.
+# ----------------------------------------------------------------------------
+# dev-changes by Marino
+webapp.resource.loader.cache = true
+webapp.resource.loader.modificationCheckInterval = 5
+velocimacro.library.autoreload = false
+velocimacro.library = /WEB-INF/VM_global_library.vm
+
+velocimacro.permissions.allow.inline = true
+velocimacro.permissions.allow.inline.to.replace.global = false
+velocimacro.permissions.allow.inline.local.scope = false
+
+velocimacro.context.localscope = false
+
+# ----------------------------------------------------------------------------
+# INTERPOLATION
+# ----------------------------------------------------------------------------
+# turn off and on interpolation of references and directives in string
+# literals.  ON by default :)
+# ----------------------------------------------------------------------------
+runtime.interpolate.string.literals = true
+
+
+# ----------------------------------------------------------------------------
+# RESOURCE MANAGEMENT
+# ----------------------------------------------------------------------------
+# Allows alternative ResourceManager and ResourceCache implementations
+# to be plugged in.
+# ----------------------------------------------------------------------------
+resource.manager.class = org.apache.velocity.runtime.resource.ResourceManagerImpl
+resource.manager.cache.class = org.apache.velocity.runtime.resource.ResourceCacheImpl
diff --git a/Java-base/tiles/src/tiles-freemarker/pom.xml b/Java-base/tiles/src/tiles-freemarker/pom.xml
new file mode 100644
index 000000000..5e6146536
--- /dev/null
+++ b/Java-base/tiles/src/tiles-freemarker/pom.xml
@@ -0,0 +1,105 @@
+<?xml version="1.0"?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.apache.tiles</groupId>
+  <artifactId>tiles-freemarker</artifactId>
+  <name>Tiles - FreeMarker Support</name>
+  <description>Support for FreeMarker in Apache Tiles. For more read http://tiles.apache.org/framework/tutorial/integration/freemarker.html</description>
+  <parent>
+      <artifactId>tiles-parent</artifactId>
+      <groupId>org.apache.tiles</groupId>
+      <version>3.1-SNAPSHOT</version>
+  </parent>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.tiles.autotag.plugin</groupId>
+        <artifactId>maven-autotag-plugin</artifactId>
+        <version>${tiles.autotag.version}</version>
+        <executions>
+            <execution>
+                <goals>
+                    <goal>generate-freemarker</goal>
+                </goals>
+                <configuration>
+                    <packageName>org.apache.tiles.freemarker.template</packageName>
+                    <requestClass>org.apache.tiles.request.Request</requestClass>
+                    <freemarkerRuntime>org.apache.tiles.request.freemarker.autotag.FreemarkerAutotagRuntime</freemarkerRuntime>
+                </configuration>
+            </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+  <dependencies>
+      <dependency>
+          <groupId>org.apache.tiles</groupId>
+          <artifactId>tiles-servlet</artifactId>
+      </dependency>
+    <dependency>
+      <groupId>org.apache.tiles</groupId>
+      <artifactId>tiles-template</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>jcl-over-slf4j</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-jdk14</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+        <groupId>javax.servlet</groupId>
+        <artifactId>servlet-api</artifactId>
+        <scope>provided</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+        <groupId>org.easymock</groupId>
+        <artifactId>easymockclassextension</artifactId>
+        <scope>test</scope>
+    </dependency>
+    <dependency>
+        <groupId>org.apache.tiles</groupId>
+        <artifactId>tiles-request-freemarker</artifactId>
+        <version>${tiles.request.version}</version>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/Java-base/tiles/src/tiles-freemarker/src/main/java/org/apache/tiles/freemarker/TilesSharedVariableFactory.java b/Java-base/tiles/src/tiles-freemarker/src/main/java/org/apache/tiles/freemarker/TilesSharedVariableFactory.java
new file mode 100644
index 000000000..a80b9a53b
--- /dev/null
+++ b/Java-base/tiles/src/tiles-freemarker/src/main/java/org/apache/tiles/freemarker/TilesSharedVariableFactory.java
@@ -0,0 +1,43 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.freemarker;
+
+import org.apache.tiles.freemarker.template.TilesFMModelRepository;
+import org.apache.tiles.request.freemarker.servlet.SharedVariableFactory;
+
+import freemarker.ext.beans.BeanModel;
+import freemarker.ext.beans.BeansWrapper;
+import freemarker.template.TemplateModel;
+
+/**
+ * Creates a shared variable that contains the Tiles Freemarker model repository.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TilesSharedVariableFactory implements SharedVariableFactory {
+
+    @Override
+    public TemplateModel create() {
+        return new BeanModel(new TilesFMModelRepository(),
+                BeansWrapper.getDefaultInstance());
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-freemarker/src/main/java/org/apache/tiles/freemarker/package-info.java b/Java-base/tiles/src/tiles-freemarker/src/main/java/org/apache/tiles/freemarker/package-info.java
new file mode 100644
index 000000000..c64cec92f
--- /dev/null
+++ b/Java-base/tiles/src/tiles-freemarker/src/main/java/org/apache/tiles/freemarker/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * Classes for supporting FreeMarker in Tiles.
+ */
+package org.apache.tiles.freemarker;
diff --git a/Java-base/tiles/src/tiles-freemarker/src/site/site.xml b/Java-base/tiles/src/tiles-freemarker/src/site/site.xml
new file mode 100644
index 000000000..2bedf4e47
--- /dev/null
+++ b/Java-base/tiles/src/tiles-freemarker/src/site/site.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<project name="Apache Tiles - Freemarker Support">
+     <skin>
+        <groupId>org.apache.maven.skins</groupId>
+        <artifactId>maven-fluido-skin</artifactId>
+        <version>1.3.0</version>
+     </skin>
+     <custom>
+        <fluidoSkin>
+        <topBarEnabled>true</topBarEnabled>
+        <sideBarEnabled>false</sideBarEnabled>
+        <searchEnabled>true</searchEnabled>
+        <gitHub>
+            <projectId>apache/tiles</projectId>
+            <ribbonOrientation>right</ribbonOrientation>
+            <ribbonColor>darkblue</ribbonColor>
+        </gitHub>
+        </fluidoSkin>
+     </custom>
+    <bannerLeft>
+        <name>Apache Tiles&#8482;</name>
+        <src>http://tiles.apache.org/images/logo.png</src>
+        <href>http://tiles.apache.org</href>
+    </bannerLeft>
+    <bannerRight>
+        <name>Apache Software Foundation</name>
+        <src>http://struts.apache.org/images/asf-logo.gif</src>
+        <href>http://www.apache.org</href>
+    </bannerRight>
+    <body>
+
+        <menu name="Apache Tiles&#8482;">
+            <item
+                   name="Welcome"
+                   href="../../index.html"/>
+            <item
+                    name="Tiles 3.0.x"
+                    href="../../framework/index.html"/>
+            <item
+                    name="Autotag 1.0.x"
+                    href="../../tiles-autotag/index.html"/>
+            <item
+                    name="Request 1.0.x"
+                    href="../../tiles-request/index.html"/>
+            <item
+                   name="Security bulletins"
+                   href="../security/index.html"/>
+            <item
+                   name="Download"
+                   href="http://tiles.apache.org/download.html"/>
+        </menu>
+
+        <menu ref="modules" />
+        <menu ref="reports" />
+
+        <footer>
+            <div class="row span12">
+                Apache Tiles, Tiles, Apache, the Apache feather logo, and the Apache Tiles
+                project logos are trademarks of The Apache Software Foundation.
+            </div>
+        </footer>
+    </body>
+</project>
diff --git a/Java-base/tiles/src/tiles-freemarker/src/test/java/org/apache/tiles/freemarker/TilesSharedVariableFactoryTest.java b/Java-base/tiles/src/tiles-freemarker/src/test/java/org/apache/tiles/freemarker/TilesSharedVariableFactoryTest.java
new file mode 100644
index 000000000..2690e20ff
--- /dev/null
+++ b/Java-base/tiles/src/tiles-freemarker/src/test/java/org/apache/tiles/freemarker/TilesSharedVariableFactoryTest.java
@@ -0,0 +1,45 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.freemarker;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+import freemarker.ext.beans.BeanModel;
+
+/**
+ * Tests {@link SharedVariableFactory}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TilesSharedVariableFactoryTest {
+
+    /**
+     * Test method for {@link org.apache.tiles.freemarker.TilesSharedVariableFactory#create()}.
+     */
+    @Test
+    public void testCreate() {
+        TilesSharedVariableFactory factory = new TilesSharedVariableFactory();
+        assertTrue(factory.create() instanceof BeanModel);
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-jsp/pom.xml b/Java-base/tiles/src/tiles-jsp/pom.xml
new file mode 100644
index 000000000..443b32f86
--- /dev/null
+++ b/Java-base/tiles/src/tiles-jsp/pom.xml
@@ -0,0 +1,183 @@
+<?xml version="1.0"?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+  <parent>
+    <groupId>org.apache.tiles</groupId>
+    <artifactId>tiles-parent</artifactId>
+    <version>3.1-SNAPSHOT</version>
+  </parent>
+
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>tiles-jsp</artifactId>
+  <packaging>jar</packaging>
+  <name>Tiles - JSP support</name>
+  <description>Tiles JSP support: Classes and tag libraries to use Tiles in a
+  JSP environment.</description>
+
+  <properties>
+      <tiles.osgi.symbolicName>org.apache.tiles.jsp</tiles.osgi.symbolicName>
+  </properties>
+
+  <build>
+    <resources>
+      <resource>
+        <directory>src/main/resources</directory>
+        <excludes>
+          <exclude>LICENSE.txt</exclude>
+          <exclude>NOTICE.txt</exclude>
+        </excludes>
+      </resource>
+      <resource>
+        <directory>src/main/resources</directory>
+        <includes>
+          <include>LICENSE.txt</include>
+          <include>NOTICE.txt</include>
+        </includes>
+        <targetPath>META-INF</targetPath>
+      </resource>
+    </resources>
+
+    <plugins>
+      <plugin>
+        <artifactId>maven-jar-plugin</artifactId>
+        <configuration>
+          <archive>
+            <manifest>
+            </manifest>
+          </archive>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.tiles.autotag.plugin</groupId>
+        <artifactId>maven-autotag-plugin</artifactId>
+        <version>${tiles.autotag.version}</version>
+        <executions>
+            <execution>
+                <goals>
+                    <goal>generate-jsp</goal>
+                </goals>
+                <configuration>
+                    <taglibURI>http://tiles.apache.org/tags-tiles</taglibURI>
+                    <packageName>org.apache.tiles.jsp.taglib</packageName>
+                    <requestClass>org.apache.tiles.request.Request</requestClass>
+                    <jspRuntime>org.apache.tiles.request.jsp.autotag.JspAutotagRuntime</jspRuntime>
+                </configuration>
+            </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>net.sourceforge.maven-taglib</groupId>
+        <artifactId>maven-taglib-plugin</artifactId>
+        <version>2.4</version>
+        <configuration>
+          <parseHtml>true</parseHtml>
+          <srcDir>${project.build.outputDirectory}/META-INF/tld</srcDir>
+        </configuration>
+      </plugin>
+    </plugins>
+
+  </build>
+
+  <reporting>
+    <plugins>
+      <plugin>
+        <groupId>net.sourceforge.maven-taglib</groupId>
+        <artifactId>maven-taglib-plugin</artifactId>
+        <version>2.4</version>
+        <configuration>
+          <parseHtml>true</parseHtml>
+          <srcDir>${project.build.outputDirectory}/META-INF/tld</srcDir>
+        </configuration>
+      </plugin>
+    </plugins>
+  </reporting>
+
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.tiles</groupId>
+      <artifactId>tiles-servlet</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tiles</groupId>
+      <artifactId>tiles-template</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>jcl-over-slf4j</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-jdk14</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>javax.servlet</groupId>
+      <artifactId>servlet-api</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>javax.servlet.jsp</groupId>
+      <artifactId>jsp-api</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.easymock</groupId>
+      <artifactId>easymock</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.easymock</groupId>
+      <artifactId>easymockclassextension</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.shale</groupId>
+      <artifactId>shale-test</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+        <groupId>org.apache.tiles</groupId>
+        <artifactId>tiles-request-jsp</artifactId>
+        <version>${tiles.request.version}</version>
+    </dependency>
+  </dependencies>
+
+</project>
diff --git a/Java-base/tiles/src/tiles-jsp/src/main/java/org/apache/tiles/jsp/taglib/UseAttributeTag.java b/Java-base/tiles/src/tiles-jsp/src/main/java/org/apache/tiles/jsp/taglib/UseAttributeTag.java
new file mode 100644
index 000000000..f9887f288
--- /dev/null
+++ b/Java-base/tiles/src/tiles-jsp/src/main/java/org/apache/tiles/jsp/taglib/UseAttributeTag.java
@@ -0,0 +1,226 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.jsp.taglib;
+
+import java.io.IOException;
+
+import javax.servlet.jsp.JspException;
+import javax.servlet.jsp.tagext.SimpleTagSupport;
+import javax.servlet.jsp.tagext.TagData;
+import javax.servlet.jsp.tagext.TagExtraInfo;
+import javax.servlet.jsp.tagext.VariableInfo;
+
+import org.apache.tiles.autotag.core.runtime.AutotagRuntime;
+import org.apache.tiles.request.Request;
+import org.apache.tiles.template.ImportAttributeModel;
+
+/**
+ * Exposes am attribute as a scripting variable within the page.
+ *
+ * @since Tiles 1.0
+ * @version $Rev$ $Date$
+ */
+public class UseAttributeTag extends SimpleTagSupport {
+
+    /**
+     * The template model.
+     */
+    private ImportAttributeModel model = new ImportAttributeModel();
+
+    /**
+     * The id of the imported scripting variable.
+     */
+    private String id;
+
+    /**
+     * The scope name.
+     */
+    private String scopeName = null;
+
+    /**
+     * The name of the attribute.
+     */
+    private String name = null;
+
+    /**
+     * Flag that, if <code>true</code>, ignores exceptions.
+     */
+    private boolean ignore = false;
+
+    /**
+     * Class name of object.
+     */
+    private String classname = null;
+
+    /**
+     * Returns the id of the imported scripting variable.
+     *
+     * @return The id of the imported scripting variable.
+     * @since 2.2.0
+     */
+    public String getId() {
+        return id;
+    }
+
+    /**
+     * Sets the id of the imported scripting variable.
+     *
+     * @param id
+     *            The id of the imported scripting variable.
+     * @since 2.2.0
+     */
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    /**
+     * Set the scope.
+     *
+     * @param scope
+     *            Scope.
+     */
+    public void setScope(String scope) {
+        this.scopeName = scope;
+    }
+
+    /**
+     * Get scope.
+     *
+     * @return Scope.
+     */
+    public String getScope() {
+        return scopeName;
+    }
+
+    /**
+     * Get the name.
+     *
+     * @return Name.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Set the name.
+     *
+     * @param name
+     *            The new name
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * Set ignore flag.
+     *
+     * @param ignore
+     *            default: <code>false</code>: Exception is thrown when
+     *            attribute is not found, set to <code>
+     *               true</code> to
+     *            ignore missing attributes silently
+     */
+    public void setIgnore(boolean ignore) {
+        this.ignore = ignore;
+    }
+
+    /**
+     * Get ignore flag.
+     *
+     * @return default: <code>false</code>: Exception is thrown when attribute
+     *         is not found, set to <code>
+     *         true</code> to ignore missing
+     *         attributes silently
+     */
+    public boolean isIgnore() {
+        return ignore;
+    }
+
+    /**
+     * Get class name.
+     *
+     * @return class name
+     */
+    public String getClassname() {
+        return classname;
+
+    }
+
+    /**
+     * Set the class name.
+     *
+     * @param name
+     *            The new class name.
+     */
+    public void setClassname(String name) {
+        this.classname = name;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void doTag() throws JspException, IOException {
+        AutotagRuntime<Request> runtime = new org.apache.tiles.request.jsp.autotag.JspAutotagRuntime();
+        if (runtime instanceof SimpleTagSupport) {
+            SimpleTagSupport tag = (SimpleTagSupport) runtime;
+            tag.setJspContext(getJspContext());
+            tag.setJspBody(getJspBody());
+            tag.setParent(getParent());
+            tag.doTag();
+        }
+        Request request = runtime.createRequest();
+        model.execute(name, scopeName, id, ignore, request);
+    }
+
+    /**
+     * Returns the scripting variable to use.
+     *
+     * @return The scripting variable.
+     */
+    public String getScriptingVariable() {
+        return id == null ? getName() : id;
+    }
+
+    /**
+     * Implementation of <code>TagExtraInfo</code> which identifies the
+     * scripting object(s) to be made visible.
+     */
+    public static class Tei extends TagExtraInfo {
+
+        /** {@inheritDoc} */
+        @Override
+        public VariableInfo[] getVariableInfo(TagData data) {
+            String classname = data.getAttributeString("classname");
+            if (classname == null) {
+                classname = "java.lang.Object";
+            }
+
+            String id = data.getAttributeString("id");
+            if (id == null) {
+                id = data.getAttributeString("name");
+            }
+
+            return new VariableInfo[] { new VariableInfo(id, classname, true,
+                    VariableInfo.AT_END) };
+
+        }
+    }
+}
diff --git a/Java-base/tiles/src/tiles-jsp/src/main/java/org/apache/tiles/jsp/taglib/package-info.java b/Java-base/tiles/src/tiles-jsp/src/main/java/org/apache/tiles/jsp/taglib/package-info.java
new file mode 100644
index 000000000..c57c45100
--- /dev/null
+++ b/Java-base/tiles/src/tiles-jsp/src/main/java/org/apache/tiles/jsp/taglib/package-info.java
@@ -0,0 +1,27 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * The "tiles-jsp" tag library contains tags that are useful to create
+ * templates, subpages other reusable view parts using the "tiles-core"
+ * package.
+ */
+package org.apache.tiles.jsp.taglib;
+
diff --git a/Java-base/tiles/src/tiles-jsp/src/main/resources/LICENSE.txt b/Java-base/tiles/src/tiles-jsp/src/main/resources/LICENSE.txt
new file mode 100644
index 000000000..d64569567
--- /dev/null
+++ b/Java-base/tiles/src/tiles-jsp/src/main/resources/LICENSE.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/Java-base/tiles/src/tiles-jsp/src/main/resources/META-INF/tld/tiles-extras-jsp.tld b/Java-base/tiles/src/tiles-jsp/src/main/resources/META-INF/tld/tiles-extras-jsp.tld
new file mode 100644
index 000000000..60cad303c
--- /dev/null
+++ b/Java-base/tiles/src/tiles-jsp/src/main/resources/META-INF/tld/tiles-extras-jsp.tld
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<taglib
+  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
+  xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  version="2.1">
+   <description>
+   <![CDATA[
+   <p>This tag library provides Tiles tags.</p>
+   ]]>
+   </description>
+   <tlib-version>1.2</tlib-version>
+   <short-name>tilesx</short-name>
+   <uri>http://tiles.apache.org/tags-tiles-extras</uri>
+   <tag>
+      <description>
+      <![CDATA[
+      <p><strong>Use attribute value inside page.</strong></p>
+      <p>Declare a Java variable, and an attribute in the specified scope,
+      using its attribute value.</p>
+      <p>Java variable and attribute will have the name specified by 'id',
+      or the original name if not specified.</p>
+      ]]>
+      </description>
+      <name>useAttribute</name>
+      <tag-class>org.apache.tiles.jsp.taglib.UseAttributeTag</tag-class>
+      <tei-class>org.apache.tiles.jsp.taglib.UseAttributeTag$Tei</tei-class>
+      <body-content>empty</body-content>
+      <attribute>
+         <description>
+         <![CDATA[
+         <p>Declared attribute and variable name.</p>
+         ]]>
+         </description>
+         <name>id</name>
+         <required>false</required>
+         <rtexprvalue>true</rtexprvalue>
+      </attribute>
+      <attribute>
+         <description>
+         <![CDATA[
+         <p>Class of the declared variable.</p>
+         ]]>
+         </description>
+         <name>classname</name>
+         <required>false</required>
+         <rtexprvalue>true</rtexprvalue>
+      </attribute>
+      <attribute>
+         <description>
+         <![CDATA[
+         <p>Scope of the declared attribute. Default to 'page'.</p>
+         ]]>
+         </description>
+         <name>scope</name>
+         <required>false</required>
+         <rtexprvalue>false</rtexprvalue>
+      </attribute>
+      <attribute>
+         <description>
+         <![CDATA[
+         <p>Attribute name.</p>
+         ]]>
+         </description>
+         <name>name</name>
+         <required>true</required>
+         <rtexprvalue>true</rtexprvalue>
+      </attribute>
+      <attribute>
+         <description>
+         <![CDATA[
+         <p>
+         If this attribute is set to true, and the attribute specified by the name
+         does not exist, simply return without error. The default value is false, which will
+         cause a runtime exception to be thrown.
+         </p>
+         ]]>
+         </description>
+         <name>ignore</name>
+         <required>false</required>
+         <rtexprvalue>true</rtexprvalue>
+         <type>boolean</type>
+      </attribute>
+   </tag>
+</taglib>
+
diff --git a/Java-base/tiles/src/tiles-jsp/src/main/resources/NOTICE.txt b/Java-base/tiles/src/tiles-jsp/src/main/resources/NOTICE.txt
new file mode 100644
index 000000000..1f13ff856
--- /dev/null
+++ b/Java-base/tiles/src/tiles-jsp/src/main/resources/NOTICE.txt
@@ -0,0 +1,6 @@
+   Apache Tiles
+   Copyright 1999-2009 The Apache Software Foundation
+
+   This product includes software developed at
+   The Apache Software Foundation (http://www.apache.org/).
+
diff --git a/Java-base/tiles/src/tiles-jsp/src/site/site.xml b/Java-base/tiles/src/tiles-jsp/src/site/site.xml
new file mode 100644
index 000000000..cf33f2096
--- /dev/null
+++ b/Java-base/tiles/src/tiles-jsp/src/site/site.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<project name="Apache Tiles - JSP support">
+     <skin>
+        <groupId>org.apache.maven.skins</groupId>
+        <artifactId>maven-fluido-skin</artifactId>
+        <version>1.3.0</version>
+     </skin>
+     <custom>
+        <fluidoSkin>
+        <topBarEnabled>true</topBarEnabled>
+        <sideBarEnabled>false</sideBarEnabled>
+        <searchEnabled>true</searchEnabled>
+        <gitHub>
+            <projectId>apache/tiles</projectId>
+            <ribbonOrientation>right</ribbonOrientation>
+            <ribbonColor>darkblue</ribbonColor>
+        </gitHub>
+        </fluidoSkin>
+     </custom>
+    <bannerLeft>
+        <name>Apache Tiles&#8482;</name>
+        <src>http://tiles.apache.org/images/logo.png</src>
+        <href>http://tiles.apache.org</href>
+    </bannerLeft>
+    <bannerRight>
+        <name>Apache Software Foundation</name>
+        <src>http://struts.apache.org/images/asf-logo.gif</src>
+        <href>http://www.apache.org</href>
+    </bannerRight>
+    <body>
+
+        <menu name="Apache Tiles&#8482;">
+            <item
+                   name="Welcome"
+                   href="../../index.html"/>
+            <item
+                    name="Tiles 3.0.x"
+                    href="../../framework/index.html"/>
+            <item
+                    name="Autotag 1.0.x"
+                    href="../../tiles-autotag/index.html"/>
+            <item
+                    name="Request 1.0.x"
+                    href="../../tiles-request/index.html"/>
+            <item
+                   name="Security bulletins"
+                   href="../security/index.html"/>
+            <item
+                   name="Download"
+                   href="http://tiles.apache.org/download.html"/>
+        </menu>
+
+        <menu ref="modules" />
+        <menu ref="reports" />
+
+        <footer>
+            <div class="row span12">
+                Apache Tiles, Tiles, Apache, the Apache feather logo, and the Apache Tiles
+                project logos are trademarks of The Apache Software Foundation.
+            </div>
+        </footer>
+    </body>
+</project>
diff --git a/Java-base/tiles/src/tiles-jsp/src/test/java/org/apache/tiles/jsp/taglib/UseAttributeTagTest.java b/Java-base/tiles/src/tiles-jsp/src/test/java/org/apache/tiles/jsp/taglib/UseAttributeTagTest.java
new file mode 100644
index 000000000..4c59ea068
--- /dev/null
+++ b/Java-base/tiles/src/tiles-jsp/src/test/java/org/apache/tiles/jsp/taglib/UseAttributeTagTest.java
@@ -0,0 +1,214 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.jsp.taglib;
+
+import static org.easymock.EasyMock.*;
+import static org.easymock.classextension.EasyMock.*;
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.jsp.JspException;
+import javax.servlet.jsp.PageContext;
+import javax.servlet.jsp.tagext.JspFragment;
+import javax.servlet.jsp.tagext.JspTag;
+import javax.servlet.jsp.tagext.TagData;
+import javax.servlet.jsp.tagext.VariableInfo;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.AttributeContext;
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.access.TilesAccess;
+import org.apache.tiles.request.ApplicationAccess;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.jsp.JspRequest;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests {@link UseAttributeTag}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class UseAttributeTagTest {
+
+    /**
+     * The tag to test.
+     */
+    private UseAttributeTag tag;
+
+    /**
+     * Sets up the test.
+     */
+    @Before
+    public void setUp() {
+        tag = new UseAttributeTag();
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.jsp.taglib.UseAttributeTag#execute(org.apache.tiles.request.Request)}.
+     * @throws IOException
+     * @throws JspException
+     */
+    @Test
+    public void testExecute() throws JspException, IOException {
+        JspFragment jspBody = createMock(JspFragment.class);
+        PageContext pageContext = createMock(PageContext.class);
+        JspTag parent = createMock(JspTag.class);
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        HttpServletRequest httpServletRequest = createMock(HttpServletRequest.class);
+        HttpServletResponse httpServletResponse = createMock(HttpServletResponse.class);
+        @SuppressWarnings("unchecked")
+        Map<String, Object> applicationScope = createMock(Map.class);
+        TilesContainer container = createMock(TilesContainer.class);
+        AttributeContext attributeContext = createMock(AttributeContext.class);
+        Attribute attribute = createMock(Attribute.class);
+        expect(pageContext.getAttribute(
+                ApplicationAccess.APPLICATION_CONTEXT_ATTRIBUTE,
+                PageContext.APPLICATION_SCOPE)).andReturn(applicationContext);
+        expect(applicationContext.getApplicationScope()).andReturn(applicationScope).anyTimes();
+        expect(pageContext.getRequest()).andReturn(httpServletRequest);
+        expect(pageContext.getResponse()).andReturn(httpServletResponse);
+        expect(pageContext.getAttribute(TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME, PageContext.REQUEST_SCOPE)).andReturn(container);
+        expect(container.getAttributeContext(isA(JspRequest.class))).andReturn(attributeContext);
+        expect(attributeContext.getAttribute("name")).andReturn(attribute);
+        expect(container.evaluate(isA(Attribute.class), isA(JspRequest.class))).andReturn(new Integer(1));
+        pageContext.setAttribute("id", new Integer(1), PageContext.PAGE_SCOPE);
+        replay(jspBody, pageContext, parent,
+               applicationContext, httpServletRequest, httpServletResponse,
+               applicationScope, container, attributeContext, attribute);
+        tag.setName("name");
+        tag.setScope("page");
+        tag.setId("id");
+        tag.setIgnore(false);
+        tag.setJspContext(pageContext);
+        tag.setJspBody(jspBody);
+        tag.setParent(parent);
+        tag.doTag();
+        verify(jspBody, pageContext, parent,
+               applicationContext, httpServletRequest, httpServletResponse,
+               container, attributeContext, attribute);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.jsp.taglib.UseAttributeTag#setId(java.lang.String)}.
+     */
+    @Test
+    public void testSetId() {
+        tag.setId("id");
+        assertEquals("id", tag.getId());
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.jsp.taglib.UseAttributeTag#getScope()}.
+     */
+    @Test
+    public void testGetScope() {
+        tag.setScope("scope");
+        assertEquals("scope", tag.getScope());
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.jsp.taglib.UseAttributeTag#setName(java.lang.String)}.
+     */
+    @Test
+    public void testSetName() {
+        tag.setName("name");
+        assertEquals("name", tag.getName());
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.jsp.taglib.UseAttributeTag#setIgnore(boolean)}.
+     */
+    @Test
+    public void testSetIgnore() {
+        tag.setIgnore(true);
+        assertTrue(tag.isIgnore());
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.jsp.taglib.UseAttributeTag#setClassname(java.lang.String)}.
+     */
+    @Test
+    public void testSetClassname() {
+        tag.setClassname("classname");
+        assertEquals("classname", tag.getClassname());
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.jsp.taglib.UseAttributeTag#getScriptingVariable()}.
+     */
+    @Test
+    public void testGetScriptingVariable() {
+        tag.setName("name");
+        assertEquals("name", tag.getScriptingVariable());
+        tag.setId("id");
+        assertEquals("id", tag.getScriptingVariable());
+    }
+
+    /**
+     * Tests {@link UseAttributeTag.Tei}.
+     */
+    @Test
+    public void testTei() {
+        TagData tagData = createMock(TagData.class);
+
+        expect(tagData.getAttributeString("classname")).andReturn("my.Clazz");
+        expect(tagData.getAttributeString("id")).andReturn("id");
+
+        replay(tagData);
+        UseAttributeTag.Tei tei = new UseAttributeTag.Tei();
+        VariableInfo[] infos = tei.getVariableInfo(tagData);
+        assertEquals(1, infos.length);
+        VariableInfo info = infos[0];
+        assertEquals("id", info.getVarName());
+        assertEquals("my.Clazz", info.getClassName());
+        assertTrue(info.getDeclare());
+        assertEquals(VariableInfo.AT_END, info.getScope());
+        verify(tagData);
+    }
+
+    /**
+     * Tests {@link UseAttributeTag.Tei}.
+     */
+    @Test
+    public void testTeiDefaults() {
+        TagData tagData = createMock(TagData.class);
+
+        expect(tagData.getAttributeString("classname")).andReturn(null);
+        expect(tagData.getAttributeString("id")).andReturn(null);
+        expect(tagData.getAttributeString("name")).andReturn("name");
+
+        replay(tagData);
+        UseAttributeTag.Tei tei = new UseAttributeTag.Tei();
+        VariableInfo[] infos = tei.getVariableInfo(tagData);
+        assertEquals(1, infos.length);
+        VariableInfo info = infos[0];
+        assertEquals("name", info.getVarName());
+        assertEquals("java.lang.Object", info.getClassName());
+        assertTrue(info.getDeclare());
+        assertEquals(VariableInfo.AT_END, info.getScope());
+        verify(tagData);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-mvel/pom.xml b/Java-base/tiles/src/tiles-mvel/pom.xml
new file mode 100644
index 000000000..8169292f2
--- /dev/null
+++ b/Java-base/tiles/src/tiles-mvel/pom.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0"?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+  <parent>
+    <groupId>org.apache.tiles</groupId>
+    <artifactId>tiles-parent</artifactId>
+    <version>3.1-SNAPSHOT</version>
+  </parent>
+
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>tiles-mvel</artifactId>
+  <packaging>jar</packaging>
+  <name>Tiles - MVEL support</name>
+  <description>Tiles MVEL support: Classes and tag libraries to use MVEL as an expression language in attribute expressions.</description>
+
+  <properties>
+      <tiles.osgi.symbolicName>org.apache.tiles.mvel</tiles.osgi.symbolicName>
+      <!-- decrease this whenever possible -->
+      <checkstyle.maxAllowedViolations>4</checkstyle.maxAllowedViolations>
+  </properties>
+
+  <build>
+    <resources>
+      <resource>
+        <directory>src/main/resources</directory>
+        <excludes>
+          <exclude>LICENSE.txt</exclude>
+          <exclude>NOTICE.txt</exclude>
+        </excludes>
+      </resource>
+      <resource>
+        <directory>src/main/resources</directory>
+        <includes>
+          <include>LICENSE.txt</include>
+          <include>NOTICE.txt</include>
+        </includes>
+        <targetPath>META-INF</targetPath>
+      </resource>
+    </resources>
+
+    <plugins>
+      <plugin>
+        <artifactId>maven-jar-plugin</artifactId>
+        <configuration>
+          <archive>
+            <manifest>
+            </manifest>
+          </archive>
+        </configuration>
+      </plugin>
+    </plugins>
+
+  </build>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.tiles</groupId>
+      <artifactId>tiles-core</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>jcl-over-slf4j</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-jdk14</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.easymock</groupId>
+      <artifactId>easymockclassextension</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.mvel</groupId>
+      <artifactId>mvel2</artifactId>
+    </dependency>
+  </dependencies>
+
+</project>
diff --git a/Java-base/tiles/src/tiles-mvel/src/main/java/org/apache/tiles/mvel/MVELAttributeEvaluator.java b/Java-base/tiles/src/tiles-mvel/src/main/java/org/apache/tiles/mvel/MVELAttributeEvaluator.java
new file mode 100644
index 000000000..13f21c700
--- /dev/null
+++ b/Java-base/tiles/src/tiles-mvel/src/main/java/org/apache/tiles/mvel/MVELAttributeEvaluator.java
@@ -0,0 +1,72 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.mvel;
+
+import org.apache.tiles.context.TilesRequestContextHolder;
+import org.apache.tiles.evaluator.AbstractAttributeEvaluator;
+import org.apache.tiles.request.Request;
+import org.mvel2.MVEL;
+import org.mvel2.integration.VariableResolverFactory;
+
+/**
+ * Allows to use MVEL as the language to evaluate attribute values.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public class MVELAttributeEvaluator extends AbstractAttributeEvaluator {
+
+    /**
+     * Holds the Tiles request context of the current thread.
+     */
+    private TilesRequestContextHolder requestHolder;
+
+    /**
+     * Resolves variables when starting from the root.
+     *
+     * @since 2.2.0
+     */
+    private VariableResolverFactory variableResolverFactory;
+
+    /**
+     * Constructor.
+     *
+     * @param requestHolder The object that holds the Tiles request context of
+     * the current thread.
+     * @param variableResolverFactory The resolver factory to use.
+     * @since 2.2.0
+     */
+    public MVELAttributeEvaluator(TilesRequestContextHolder requestHolder,
+            VariableResolverFactory variableResolverFactory) {
+        this.requestHolder = requestHolder;
+        this.variableResolverFactory = variableResolverFactory;
+    }
+
+    /** {@inheritDoc} */
+    public Object evaluate(String expression, Request request) {
+        if (expression == null) {
+            throw new IllegalArgumentException("The expression parameter cannot be null");
+        }
+        requestHolder.setTilesRequestContext(request);
+        return MVEL.eval(expression, variableResolverFactory);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-mvel/src/main/java/org/apache/tiles/mvel/ReadOnlyVariableResolverFactory.java b/Java-base/tiles/src/tiles-mvel/src/main/java/org/apache/tiles/mvel/ReadOnlyVariableResolverFactory.java
new file mode 100644
index 000000000..aa3b2e3a0
--- /dev/null
+++ b/Java-base/tiles/src/tiles-mvel/src/main/java/org/apache/tiles/mvel/ReadOnlyVariableResolverFactory.java
@@ -0,0 +1,147 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.mvel;
+
+import java.util.HashMap;
+
+import org.apache.tiles.context.TilesRequestContextHolder;
+import org.mvel2.UnresolveablePropertyException;
+import org.mvel2.integration.VariableResolver;
+import org.mvel2.integration.impl.BaseVariableResolverFactory;
+
+/**
+ * A base variable resolver factory that is read-only.
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class ReadOnlyVariableResolverFactory extends
+        BaseVariableResolverFactory {
+
+    /**
+     * The Tiles request holder.
+     */
+    protected TilesRequestContextHolder requestHolder;
+
+    /**
+     * Constructor.
+     *
+     * @param requestHolder The Tiles request holder.
+     * @since 3..0
+     */
+    public ReadOnlyVariableResolverFactory(TilesRequestContextHolder requestHolder) {
+        this.requestHolder = requestHolder;
+        variableResolvers = new HashMap<String, VariableResolver>();
+    }
+
+    /** {@inheritDoc} */
+    public VariableResolver createVariable(String name, Object value) {
+        if (nextFactory != null) {
+            return nextFactory.createVariable(name, value);
+        }
+        throw new UnsupportedOperationException("This variable resolver factory is read only");
+    }
+
+    /** {@inheritDoc} */
+    public VariableResolver createVariable(String name, Object value,
+            Class<?> type) {
+        variableResolvers = new HashMap<String, VariableResolver>();
+        if (nextFactory != null) {
+            return nextFactory.createVariable(name, value, type);
+        }
+        throw new UnsupportedOperationException("This variable resolver factory is read only");
+    }
+
+    /** {@inheritDoc} */
+    public boolean isResolveable(String name) {
+        return isTarget(name) || isNextResolveable(name);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public VariableResolver getVariableResolver(String name) {
+        if (isResolveable(name)) {
+            if (variableResolvers != null && variableResolvers.containsKey(name)) {
+                return variableResolvers.get(name);
+            } else if (isTarget(name)) {
+                VariableResolver variableResolver = createVariableResolver(name);
+                variableResolvers.put(name, variableResolver);
+                return variableResolver;
+            } else if (nextFactory != null) {
+                return nextFactory.getVariableResolver(name);
+            }
+        }
+
+        throw new UnresolveablePropertyException("unable to resolve variable '" + name + "'");
+    }
+
+    /**
+     * Creates a variable resolver.
+     *
+     * @param name The name of the property.
+     * @return The variable resolver.
+     * @since 3.0.0
+     */
+    public abstract VariableResolver createVariableResolver(String name);
+
+    /**
+     * Base variable resolver.
+     *
+     * @version $Rev$ $Date$
+     * @since 3.0.0
+     */
+    public abstract static class ReadOnlyVariableResolver implements VariableResolver {
+
+        /**
+         * The name of the property.
+         */
+        protected String name;
+
+        /**
+         * Constructor.
+         *
+         * @param name The name of the property.
+         * @since 2.2.0
+         */
+        public ReadOnlyVariableResolver(String name) {
+            this.name = name;
+        }
+
+        /** {@inheritDoc} */
+        public int getFlags() {
+            return 0;
+        }
+
+        /** {@inheritDoc} */
+        public String getName() {
+            return name;
+        }
+
+        /** {@inheritDoc} */
+        public void setStaticType(@SuppressWarnings("rawtypes") Class type) {
+            // Does nothing for the moment.
+        }
+
+        /** {@inheritDoc} */
+        public void setValue(Object value) {
+            throw new UnsupportedOperationException("This resolver is read-only");
+        }
+    }
+}
diff --git a/Java-base/tiles/src/tiles-mvel/src/main/java/org/apache/tiles/mvel/ScopeVariableResolverFactory.java b/Java-base/tiles/src/tiles-mvel/src/main/java/org/apache/tiles/mvel/ScopeVariableResolverFactory.java
new file mode 100644
index 000000000..7cb21da03
--- /dev/null
+++ b/Java-base/tiles/src/tiles-mvel/src/main/java/org/apache/tiles/mvel/ScopeVariableResolverFactory.java
@@ -0,0 +1,104 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.mvel;
+
+import java.util.Map;
+
+import org.apache.tiles.context.TilesRequestContextHolder;
+import org.apache.tiles.request.Request;
+import org.mvel2.integration.VariableResolver;
+
+/**
+ * Resolves beans stored in request, session and application scopes.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public class ScopeVariableResolverFactory extends
+        ReadOnlyVariableResolverFactory {
+
+    /**
+     * The length of the scope suffix: "Scope".
+     */
+    private static final int SCOPE_SUFFIX_LENGTH = 5;
+
+    /**
+     * Constructor.
+     *
+     * @param requestHolder The Tiles request holder.
+     * @since 2.2.0
+     */
+    public ScopeVariableResolverFactory(TilesRequestContextHolder requestHolder) {
+        super(requestHolder);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public VariableResolver createVariableResolver(String name) {
+        return new ScopeVariableResolver(name);
+    }
+
+    /** {@inheritDoc} */
+    public boolean isTarget(String name) {
+        Request request = requestHolder.getTilesRequestContext();
+        if (name.endsWith("Scope")) {
+            String scopeName = name.substring(0, name.length() - SCOPE_SUFFIX_LENGTH);
+            for (String availableScope : request.getAvailableScopes()) {
+                if (scopeName.equals(availableScope)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Resolves a single attribute stored in request, session or application scope.
+     *
+     * @version $Rev$ $Date$
+     * @since 2.2.0
+     */
+    private class ScopeVariableResolver extends ReadOnlyVariableResolver {
+
+        /**
+         * Constructor.
+         *
+         * @param name The name of the attribute.
+         * @since 2.2.0
+         */
+        public ScopeVariableResolver(String name) {
+            super(name);
+        }
+
+        /** {@inheritDoc} */
+        @SuppressWarnings("rawtypes")
+        public Class getType() {
+            return Map.class;
+        }
+
+        /** {@inheritDoc} */
+        public Object getValue() {
+            Request request = requestHolder.getTilesRequestContext();
+            return request.getContext(name.substring(0, name.length() - SCOPE_SUFFIX_LENGTH));
+        }
+    }
+}
diff --git a/Java-base/tiles/src/tiles-mvel/src/main/java/org/apache/tiles/mvel/TilesContextBeanVariableResolverFactory.java b/Java-base/tiles/src/tiles-mvel/src/main/java/org/apache/tiles/mvel/TilesContextBeanVariableResolverFactory.java
new file mode 100644
index 000000000..2d54ad8a5
--- /dev/null
+++ b/Java-base/tiles/src/tiles-mvel/src/main/java/org/apache/tiles/mvel/TilesContextBeanVariableResolverFactory.java
@@ -0,0 +1,104 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.mvel;
+
+import org.apache.tiles.context.TilesRequestContextHolder;
+import org.apache.tiles.request.Request;
+import org.mvel2.integration.VariableResolver;
+
+/**
+ * Resolves beans stored in request, session and application scopes.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public class TilesContextBeanVariableResolverFactory extends
+        ReadOnlyVariableResolverFactory {
+
+    /**
+     * Constructor.
+     *
+     * @param requestHolder The Tiles request holder.
+     * @since 2.2.0
+     */
+    public TilesContextBeanVariableResolverFactory(TilesRequestContextHolder requestHolder) {
+        super(requestHolder);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public VariableResolver createVariableResolver(String name) {
+        return new TilesContextBeanVariableResolver(name);
+    }
+
+    /** {@inheritDoc} */
+    public boolean isTarget(String name) {
+        Request request = requestHolder.getTilesRequestContext();
+        for (String scope : request.getAvailableScopes()) {
+            if (request.getContext(scope).containsKey(name)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Resolves a single attribute stored in request, session or application scope.
+     *
+     * @version $Rev$ $Date$
+     * @since 2.2.0
+     */
+    private class TilesContextBeanVariableResolver extends ReadOnlyVariableResolver {
+
+        /**
+         * Constructor.
+         *
+         * @param name The name of the attribute.
+         * @since 2.2.0
+         */
+        public TilesContextBeanVariableResolver(String name) {
+            super(name);
+        }
+
+        /** {@inheritDoc} */
+        @SuppressWarnings("rawtypes")
+        public Class getType() {
+            Object value = getValue();
+            if (value != null) {
+                return value.getClass();
+            }
+            return Object.class;
+        }
+
+        /** {@inheritDoc} */
+        public Object getValue() {
+            Request request = requestHolder.getTilesRequestContext();
+            for (String scope : request.getAvailableScopes()) {
+                Object value = request.getContext(scope).get(name);
+                if (value != null) {
+                    return value;
+                }
+            }
+            return null;
+        }
+    }
+}
diff --git a/Java-base/tiles/src/tiles-mvel/src/main/java/org/apache/tiles/mvel/TilesContextVariableResolverFactory.java b/Java-base/tiles/src/tiles-mvel/src/main/java/org/apache/tiles/mvel/TilesContextVariableResolverFactory.java
new file mode 100644
index 000000000..0336e75e9
--- /dev/null
+++ b/Java-base/tiles/src/tiles-mvel/src/main/java/org/apache/tiles/mvel/TilesContextVariableResolverFactory.java
@@ -0,0 +1,195 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.mvel;
+
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.apache.tiles.context.TilesRequestContextHolder;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.Request;
+import org.apache.tiles.request.reflect.CannotAccessMethodException;
+import org.apache.tiles.util.CombinedBeanInfo;
+import org.mvel2.integration.VariableResolver;
+
+/**
+ * Resolves {@link org.apache.tiles.request.Request} and
+ * {@link org.apache.tiles.request.ApplicationContext} properties as variables.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public class TilesContextVariableResolverFactory extends
+        ReadOnlyVariableResolverFactory {
+
+    /**
+     * Beaninfo about {@link org.apache.tiles.request.Request} and
+     * {@link org.apache.tiles.request.ApplicationContext}.
+     */
+    private CombinedBeanInfo requestBeanInfo = new CombinedBeanInfo(
+            Request.class, ApplicationContext.class);
+
+    /**
+     * Constructor.
+     *
+     * @param requestHolder The Tiles request holder.
+     * @since 2.2.0
+     */
+    public TilesContextVariableResolverFactory(TilesRequestContextHolder requestHolder) {
+        super(requestHolder);
+    }
+
+    /** {@inheritDoc} */
+    public boolean isTarget(String name) {
+        return requestBeanInfo.getMappedDescriptors(Request.class).containsKey(
+                name)
+                || requestBeanInfo.getMappedDescriptors(
+                        ApplicationContext.class).containsKey(name);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public VariableResolver createVariableResolver(String name) {
+        VariableResolver resolver = null;
+        PropertyDescriptor descriptor = requestBeanInfo.getMappedDescriptors(Request.class).get(name);
+        if (descriptor != null) {
+            resolver = new RequestVariableResolver(name, descriptor);
+        } else {
+            descriptor = requestBeanInfo.getMappedDescriptors(ApplicationContext.class).get(name);
+            if (descriptor != null) {
+                resolver = new ApplicationVariableResolver(name, descriptor);
+            }
+        }
+        return resolver;
+    }
+
+    /**
+     * Resolves a {@link org.apache.tiles.request.Request} property as a variable.
+     *
+     * @version $Rev$ $Date$
+     * @since 2.2.0
+     */
+    private class RequestVariableResolver extends ReadOnlyVariableResolver {
+
+        /**
+         * The property descriptor.
+         */
+        private PropertyDescriptor descriptor;
+
+        /**
+         * Constructor.
+         *
+         * @param name The name of the property.
+         * @param descriptor The property descriptor.
+         * @since 2.2.0
+         */
+        public RequestVariableResolver(String name, PropertyDescriptor descriptor) {
+            super(name);
+            this.descriptor = descriptor;
+        }
+
+        /** {@inheritDoc} */
+        @SuppressWarnings("rawtypes")
+        public Class getType() {
+            return descriptor.getPropertyType();
+        }
+
+        /** {@inheritDoc} */
+        public Object getValue() {
+            Method method = descriptor.getReadMethod();
+            try {
+                return method.invoke(requestHolder.getTilesRequestContext());
+            } catch (IllegalArgumentException e) {
+                throw new CannotAccessMethodException(
+                        "Arguments are wrong for property '"
+                                + descriptor.getName() + "'", e);
+            } catch (IllegalAccessException e) {
+                throw new CannotAccessMethodException(
+                        "Cannot access getter method for property '"
+                                + descriptor.getName() + "'", e);
+            } catch (InvocationTargetException e) {
+                throw new CannotAccessMethodException(
+                        "The getter method for property '"
+                                + descriptor.getName() + "' threw an exception",
+                        e);
+            }
+        }
+    }
+
+    /**
+     * Resolves a {@link org.apache.tiles.request.ApplicationContext} property as a
+     * variable.
+     *
+     * @version $Rev$ $Date$
+     * @since 2.2.0
+     */
+    private class ApplicationVariableResolver extends ReadOnlyVariableResolver {
+
+        /**
+         * The property descriptor.
+         *
+         * @since 2.2.0
+         */
+        private PropertyDescriptor descriptor;
+
+        /**
+         * Constructor.
+         *
+         * @param name The name of the property.
+         * @param descriptor The property descriptor.
+         * @since 2.2.0
+         */
+        public ApplicationVariableResolver(String name, PropertyDescriptor descriptor) {
+            super(name);
+            this.descriptor = descriptor;
+        }
+
+        /** {@inheritDoc} */
+        @SuppressWarnings("rawtypes")
+        public Class getType() {
+            return descriptor.getPropertyType();
+        }
+
+        /** {@inheritDoc} */
+        public Object getValue() {
+            Method method = descriptor.getReadMethod();
+            try {
+                return method.invoke(requestHolder.getTilesRequestContext()
+                        .getApplicationContext());
+            } catch (IllegalArgumentException e) {
+                throw new CannotAccessMethodException(
+                        "Arguments are wrong for property '"
+                                + descriptor.getName() + "'", e);
+            } catch (IllegalAccessException e) {
+                throw new CannotAccessMethodException(
+                        "Cannot access getter method for property '"
+                                + descriptor.getName() + "'", e);
+            } catch (InvocationTargetException e) {
+                throw new CannotAccessMethodException(
+                        "The getter method for property '"
+                                + descriptor.getName() + "' threw an exception",
+                        e);
+            }
+        }
+    }
+}
diff --git a/Java-base/tiles/src/tiles-mvel/src/main/java/org/apache/tiles/mvel/package-info.java b/Java-base/tiles/src/tiles-mvel/src/main/java/org/apache/tiles/mvel/package-info.java
new file mode 100644
index 000000000..b37f16f54
--- /dev/null
+++ b/Java-base/tiles/src/tiles-mvel/src/main/java/org/apache/tiles/mvel/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * Attribute evaluator classes that can perform MVEL evaluation for attributes.
+ */
+package org.apache.tiles.mvel;
diff --git a/Java-base/tiles/src/tiles-mvel/src/site/site.xml b/Java-base/tiles/src/tiles-mvel/src/site/site.xml
new file mode 100644
index 000000000..06e8e095d
--- /dev/null
+++ b/Java-base/tiles/src/tiles-mvel/src/site/site.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<project name="Apache Tiles - MVEL Support">
+     <skin>
+        <groupId>org.apache.maven.skins</groupId>
+        <artifactId>maven-fluido-skin</artifactId>
+        <version>1.3.0</version>
+     </skin>
+     <custom>
+        <fluidoSkin>
+        <topBarEnabled>true</topBarEnabled>
+        <sideBarEnabled>false</sideBarEnabled>
+        <searchEnabled>true</searchEnabled>
+        <gitHub>
+            <projectId>apache/tiles</projectId>
+            <ribbonOrientation>right</ribbonOrientation>
+            <ribbonColor>darkblue</ribbonColor>
+        </gitHub>
+        </fluidoSkin>
+     </custom>
+    <bannerLeft>
+        <name>Apache Tiles&#8482;</name>
+        <src>http://tiles.apache.org/images/logo.png</src>
+        <href>http://tiles.apache.org</href>
+    </bannerLeft>
+    <bannerRight>
+        <name>Apache Software Foundation</name>
+        <src>http://struts.apache.org/images/asf-logo.gif</src>
+        <href>http://www.apache.org</href>
+    </bannerRight>
+    <body>
+
+        <menu name="Apache Tiles&#8482;">
+            <item
+                   name="Welcome"
+                   href="../../index.html"/>
+            <item
+                    name="Tiles 3.0.x"
+                    href="../../framework/index.html"/>
+            <item
+                    name="Autotag 1.0.x"
+                    href="../../tiles-autotag/index.html"/>
+            <item
+                    name="Request 1.0.x"
+                    href="../../tiles-request/index.html"/>
+            <item
+                   name="Security bulletins"
+                   href="../security/index.html"/>
+            <item
+                   name="Download"
+                   href="http://tiles.apache.org/download.html"/>
+        </menu>
+
+        <menu ref="modules" />
+        <menu ref="reports" />
+
+        <footer>
+            <div class="row span12">
+                Apache Tiles, Tiles, Apache, the Apache feather logo, and the Apache Tiles
+                project logos are trademarks of The Apache Software Foundation.
+            </div>
+        </footer>
+    </body>
+</project>
diff --git a/Java-base/tiles/src/tiles-mvel/src/test/java/org/apache/tiles/mvel/MVELAttributeEvaluatorTest.java b/Java-base/tiles/src/tiles-mvel/src/test/java/org/apache/tiles/mvel/MVELAttributeEvaluatorTest.java
new file mode 100644
index 000000000..96a33704e
--- /dev/null
+++ b/Java-base/tiles/src/tiles-mvel/src/test/java/org/apache/tiles/mvel/MVELAttributeEvaluatorTest.java
@@ -0,0 +1,201 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.mvel;
+
+import java.util.Arrays;
+import static org.easymock.classextension.EasyMock.*;
+import static org.junit.Assert.*;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.Expression;
+import org.apache.tiles.context.TilesRequestContextHolder;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.Request;
+import org.junit.Before;
+import org.junit.Test;
+import org.mvel2.integration.VariableResolverFactory;
+
+/**
+ * Tests {@link MVELAttributeEvaluator}.
+ *
+ * @version $Rev$ $Date$$
+ */
+public class MVELAttributeEvaluatorTest {
+
+    /**
+     * The evaluator to test.
+     */
+    private MVELAttributeEvaluator evaluator;
+
+    /**
+     * The request object to use.
+     */
+    private Request request;
+
+    /**
+     * The application context.
+     */
+    private ApplicationContext applicationContext;
+
+    /**
+     * Sets up the test.
+     */
+    @Before
+    public void setUp() {
+        TilesRequestContextHolder requestHolder = new TilesRequestContextHolder();
+        VariableResolverFactory variableResolverFactory = new ScopeVariableResolverFactory(
+                requestHolder);
+        variableResolverFactory
+                .setNextFactory(new TilesContextVariableResolverFactory(
+                        requestHolder));
+        variableResolverFactory
+                .setNextFactory(new TilesContextBeanVariableResolverFactory(
+                        requestHolder));
+        evaluator = new MVELAttributeEvaluator(requestHolder,
+                variableResolverFactory);
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+        Map<String, Object> sessionScope = new HashMap<String, Object>();
+        Map<String, Object> applicationScope = new HashMap<String, Object>();
+        requestScope.put("object1", "value");
+        sessionScope.put("object2", new Integer(1));
+        applicationScope.put("object3", new Float(2.0));
+        requestScope.put("paulaBean", new PaulaBean());
+        request = createMock(Request.class);
+        expect(request.getContext("request")).andReturn(requestScope)
+                .anyTimes();
+        expect(request.getContext("session")).andReturn(sessionScope)
+                .anyTimes();
+        expect(request.getContext("application")).andReturn(applicationScope)
+                .anyTimes();
+        expect(request.getAvailableScopes()).andReturn(
+                Arrays.asList(new String[] { "request", "session", "application" })).anyTimes();
+        applicationContext = createMock(ApplicationContext.class);
+        expect(request.getApplicationContext()).andReturn(
+                applicationContext).anyTimes();
+        replay(request, applicationContext);
+    }
+
+    /**
+     * Tests {@link MVELAttributeEvaluator#evaluate(String, Request)}.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testEvaluateNull() {
+        evaluator.evaluate((String) null, request);
+        verify(request, applicationContext);
+    }
+
+    /**
+     * Tests
+     * {@link MVELAttributeEvaluator#evaluate(Attribute, Request)}.
+     */
+    @Test
+    public void testEvaluate() {
+        Attribute attribute = new Attribute();
+        attribute.setExpressionObject(new Expression("requestScope.object1"));
+        assertEquals("The value is not correct", "value", evaluator.evaluate(
+                attribute, request));
+        attribute.setExpressionObject(new Expression("sessionScope.object2"));
+        assertEquals("The value is not correct", new Integer(1), evaluator
+                .evaluate(attribute, request));
+        attribute.setExpressionObject(new Expression("applicationScope.object3"));
+        assertEquals("The value is not correct", new Float(2.0), evaluator
+                .evaluate(attribute, request));
+        attribute.setExpressionObject(new Expression("object1"));
+        assertEquals("The value is not correct", "value", evaluator.evaluate(
+                attribute, request));
+        attribute.setExpressionObject(new Expression("object2"));
+        assertEquals("The value is not correct", new Integer(1), evaluator
+                .evaluate(attribute, request));
+        attribute.setExpressionObject(new Expression("object3"));
+        assertEquals("The value is not correct", new Float(2.0), evaluator
+                .evaluate(attribute, request));
+        attribute.setExpressionObject(new Expression("paulaBean.paula"));
+        assertEquals("The value is not correct", "Brillant", evaluator
+                .evaluate(attribute, request));
+        attribute.setExpressionObject(new Expression("'String literal'"));
+        assertEquals("The value is not correct", "String literal", evaluator
+                .evaluate(attribute, request));
+        attribute.setValue(new Integer(2));
+        assertEquals("The value is not correct", new Integer(2), evaluator
+                .evaluate(attribute, request));
+        attribute.setValue("object1");
+        assertEquals("The value has been evaluated", "object1", evaluator
+                .evaluate(attribute, request));
+        verify(request, applicationContext);
+    }
+
+    /**
+     * Tests {@link MVELAttributeEvaluator#evaluate(String, Request)}.
+     */
+    @Test
+    public void testEvaluateString() {
+        String expression = "requestScope.object1";
+        assertEquals("The value is not correct", "value", evaluator.evaluate(
+                expression, request));
+        expression = "sessionScope.object2";
+        assertEquals("The value is not correct", new Integer(1), evaluator
+                .evaluate(expression, request));
+        expression = "applicationScope.object3";
+        assertEquals("The value is not correct", new Float(2.0), evaluator
+                .evaluate(expression, request));
+        expression = "object1";
+        assertEquals("The value is not correct", "value", evaluator.evaluate(
+                expression, request));
+        expression = "object2";
+        assertEquals("The value is not correct", new Integer(1), evaluator
+                .evaluate(expression, request));
+        expression = "object3";
+        assertEquals("The value is not correct", new Float(2.0), evaluator
+                .evaluate(expression, request));
+        expression = "paulaBean.paula";
+        assertEquals("The value is not correct", "Brillant", evaluator
+                .evaluate(expression, request));
+        expression = "'String literal'";
+        assertEquals("The value is not correct", "String literal", evaluator
+                .evaluate(expression, request));
+        verify(request, applicationContext);
+    }
+
+    /**
+     * This is The Brillant Paula Bean (sic) just like it was posted to:
+     * http://thedailywtf.com/Articles/The_Brillant_Paula_Bean.aspx I hope that
+     * there is no copyright on it.
+     */
+    public static class PaulaBean {
+
+        /**
+         * Paula is brillant, really.
+         */
+        private String paula = "Brillant";
+
+        /**
+         * Returns brillant.
+         *
+         * @return "Brillant".
+         */
+        public String getPaula() {
+            return paula;
+        }
+    }
+}
diff --git a/Java-base/tiles/src/tiles-mvel/src/test/java/org/apache/tiles/mvel/ReadOnlyVariableResolverFactoryTest.java b/Java-base/tiles/src/tiles-mvel/src/test/java/org/apache/tiles/mvel/ReadOnlyVariableResolverFactoryTest.java
new file mode 100644
index 000000000..a1a7e79a5
--- /dev/null
+++ b/Java-base/tiles/src/tiles-mvel/src/test/java/org/apache/tiles/mvel/ReadOnlyVariableResolverFactoryTest.java
@@ -0,0 +1,192 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.mvel;
+
+import java.util.Arrays;
+import static org.easymock.EasyMock.*;
+import static org.easymock.classextension.EasyMock.*;
+import static org.junit.Assert.*;
+
+import org.apache.tiles.context.TilesRequestContextHolder;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.Request;
+import org.junit.Before;
+import org.junit.Test;
+import org.mvel2.UnresolveablePropertyException;
+import org.mvel2.integration.VariableResolver;
+import org.mvel2.integration.VariableResolverFactory;
+
+
+/**
+ * Tests {@link ReadOnlyVariableResolverFactory}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ReadOnlyVariableResolverFactoryTest {
+
+    /**
+     * The Tiles request.
+     */
+    private Request request;
+
+    /**
+     * The Tiles application context.
+     */
+    private ApplicationContext applicationContext;
+
+    /**
+     * The object to test.
+     */
+    private ReadOnlyVariableResolverFactory factory;
+
+    /**
+     * Sets up the object.
+     */
+    @Before
+    public void setUp() {
+        request = createMock(Request.class);
+        expect(request.getAvailableScopes()).andReturn(
+                Arrays.asList(new String[]{"request", "session", "application"})).anyTimes();
+        TilesRequestContextHolder holder = new TilesRequestContextHolder();
+        holder.setTilesRequestContext(request);
+        applicationContext = createMock(ApplicationContext.class);
+        factory = createMockBuilder(ReadOnlyVariableResolverFactory.class).withConstructor(holder).createMock();
+    }
+
+    /**
+     * Test method for {@link ScopeVariableResolverFactory#createVariable(String, Object)}.
+     */
+    @Test(expected = UnsupportedOperationException.class)
+    public void testCreateVariableStringObject() {
+        replay(factory, request, applicationContext);
+        try {
+            factory.createVariable("myName", "myValue");
+        } finally {
+            verify(factory, request, applicationContext);
+        }
+    }
+
+    /**
+     * Test method for {@link ScopeVariableResolverFactory#createVariable(String, Object)}.
+     */
+    @Test
+    public void testCreateVariableStringObjectNextFactory() {
+        VariableResolverFactory nextFactory = createMock(VariableResolverFactory.class);
+        VariableResolver resolver = createMock(VariableResolver.class);
+
+        expect(nextFactory.createVariable("myName", "myValue")).andReturn(resolver);
+
+        replay(factory, request, applicationContext, nextFactory, resolver);
+        factory.setNextFactory(nextFactory);
+        assertEquals(resolver, factory.createVariable("myName", "myValue"));
+        verify(factory, request, applicationContext, nextFactory, resolver);
+    }
+
+    /**
+     * Test method for {@link ScopeVariableResolverFactory#createVariable(String, Object, Class)}.
+     */
+    @Test(expected = UnsupportedOperationException.class)
+    public void testCreateVariableStringObjectClassOfQ() {
+        replay(factory, request, applicationContext);
+        try {
+            factory.createVariable("myName", "myValue", String.class);
+        } finally {
+            verify(factory, request, applicationContext);
+        }
+    }
+
+    /**
+     * Test method for {@link ScopeVariableResolverFactory#createVariable(String, Object, Class)}.
+     */
+    @Test
+    public void testCreateVariableStringObjectClassNextFactory() {
+        VariableResolverFactory nextFactory = createMock(VariableResolverFactory.class);
+        VariableResolver resolver = createMock(VariableResolver.class);
+
+        expect(nextFactory.createVariable("myName", "myValue", String.class)).andReturn(resolver);
+
+        replay(factory, request, applicationContext, nextFactory, resolver);
+        factory.setNextFactory(nextFactory);
+        assertEquals(resolver, factory.createVariable("myName", "myValue", String.class));
+        verify(factory, request, applicationContext, nextFactory, resolver);
+    }
+
+    /**
+     * Test method for {@link ScopeVariableResolverFactory#isResolveable(String)}.
+     */
+    @Test
+    public void testIsResolveable() {
+        expect(factory.isTarget("whatever")).andReturn(true);
+
+        replay(factory, request, applicationContext);
+        assertTrue(factory.isResolveable("whatever"));
+        verify(factory, request, applicationContext);
+    }
+
+    /**
+     * Test method for {@link ScopeVariableResolverFactory#getVariableResolver(String)}.
+     */
+    @Test
+    public void testGetVariableResolver() {
+        VariableResolverFactory nextFactory = createMock(VariableResolverFactory.class);
+        VariableResolver nextResolver = createMock(VariableResolver.class);
+        VariableResolver requestResolver = createMock(VariableResolver.class);
+        VariableResolver applicationResolver = createMock(VariableResolver.class);
+        expect(nextFactory.getVariableResolver("other")).andReturn(nextResolver);
+        expect(nextFactory.isResolveable("other")).andReturn(true);
+        expect(factory.isTarget("requestScope")).andReturn(true).anyTimes();
+        expect(factory.isTarget("applicationScope")).andReturn(true).anyTimes();
+        expect(factory.isTarget("other")).andReturn(false).anyTimes();
+        expect(factory.createVariableResolver("requestScope")).andReturn(requestResolver);
+        expect(factory.createVariableResolver("applicationScope")).andReturn(applicationResolver);
+
+        replay(factory, request, applicationContext, nextFactory, nextResolver, requestResolver, applicationResolver);
+        factory.setNextFactory(nextFactory);
+        VariableResolver resolver = factory.getVariableResolver("requestScope");
+        assertEquals(requestResolver, resolver);
+        resolver = factory.getVariableResolver("requestScope"); // again to test caching
+        assertEquals(requestResolver, resolver);
+        resolver = factory.getVariableResolver("applicationScope");
+        assertEquals(applicationResolver, resolver);
+        resolver = factory.getVariableResolver("other");
+        assertEquals(nextResolver, resolver);
+        verify(factory, request, applicationContext, nextFactory, nextResolver, requestResolver, applicationResolver);
+    }
+
+    /**
+     * Test method for {@link ScopeVariableResolverFactory#getVariableResolver(String)}.
+     */
+    @Test(expected = UnresolveablePropertyException.class)
+    public void testGetVariableResolverNotResolvable() {
+        VariableResolverFactory nextFactory = createMock(VariableResolverFactory.class);
+
+        expect(factory.isTarget("other")).andReturn(false).anyTimes();
+        expect(nextFactory.isResolveable("other")).andReturn(false);
+
+        replay(factory, request, applicationContext, nextFactory);
+        try {
+            factory.setNextFactory(nextFactory);
+            factory.getVariableResolver("other");
+        } finally {
+            verify(factory, request, applicationContext, nextFactory);
+        }
+    }
+}
diff --git a/Java-base/tiles/src/tiles-mvel/src/test/java/org/apache/tiles/mvel/ReadOnlyVariableResolverTest.java b/Java-base/tiles/src/tiles-mvel/src/test/java/org/apache/tiles/mvel/ReadOnlyVariableResolverTest.java
new file mode 100644
index 000000000..0bdb8b34b
--- /dev/null
+++ b/Java-base/tiles/src/tiles-mvel/src/test/java/org/apache/tiles/mvel/ReadOnlyVariableResolverTest.java
@@ -0,0 +1,90 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.mvel;
+
+import static org.easymock.classextension.EasyMock.*;
+import static org.junit.Assert.*;
+
+import org.apache.tiles.mvel.ReadOnlyVariableResolverFactory.ReadOnlyVariableResolver;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests {@link ReadOnlyVariableResolver}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ReadOnlyVariableResolverTest {
+
+    /**
+     * The resolver to test.
+     */
+    private ReadOnlyVariableResolver resolver;
+
+    /**
+     * Sets up the test.
+     */
+    @Before
+    public void setUp() {
+        resolver = createMockBuilder(ReadOnlyVariableResolver.class).withConstructor("name").createMock();
+    }
+
+    /**
+     * Test method for {@link ReadOnlyVariableResolverFactory.ReadOnlyVariableResolver#getFlags()}.
+     */
+    @Test
+    public void testGetFlags() {
+        replay(resolver);
+        assertEquals(0, resolver.getFlags());
+        verify(resolver);
+    }
+
+    /**
+     * Test method for {@link ReadOnlyVariableResolverFactory.ReadOnlyVariableResolver#getName()}.
+     */
+    @Test
+    public void testGetName() {
+        replay(resolver);
+        assertEquals("name", resolver.getName());
+        verify(resolver);
+    }
+
+    /**
+     * Test method for {@link ReadOnlyVariableResolverFactory.ReadOnlyVariableResolver#setStaticType(java.lang.Class)}.
+     */
+    @Test
+    public void testSetStaticType() {
+        replay(resolver);
+        resolver.setStaticType(Object.class);
+        verify(resolver);
+    }
+
+    /**
+     * Test method for {@link ReadOnlyVariableResolverFactory.ReadOnlyVariableResolver#setValue(java.lang.Object)}.
+     */
+    @Test(expected = UnsupportedOperationException.class)
+    public void testSetValue() {
+        replay(resolver);
+        resolver.setValue("whatever");
+        verify(resolver);
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-mvel/src/test/java/org/apache/tiles/mvel/ScopeVariableResolverFactoryTest.java b/Java-base/tiles/src/tiles-mvel/src/test/java/org/apache/tiles/mvel/ScopeVariableResolverFactoryTest.java
new file mode 100644
index 000000000..bb3693c93
--- /dev/null
+++ b/Java-base/tiles/src/tiles-mvel/src/test/java/org/apache/tiles/mvel/ScopeVariableResolverFactoryTest.java
@@ -0,0 +1,114 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.mvel;
+
+import java.util.Arrays;
+import static org.easymock.EasyMock.*;
+import static org.easymock.classextension.EasyMock.*;
+import static org.junit.Assert.*;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tiles.context.TilesRequestContextHolder;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.Request;
+import org.junit.Before;
+import org.junit.Test;
+import org.mvel2.integration.VariableResolver;
+
+
+/**
+ * Tests {@link ScopeVariableResolverFactory}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ScopeVariableResolverFactoryTest {
+
+    /**
+     * The Tiles request.
+     */
+    private Request request;
+
+    /**
+     * The Tiles application context.
+     */
+    private ApplicationContext applicationContext;
+
+    /**
+     * The object to test.
+     */
+    private ScopeVariableResolverFactory factory;
+
+    /**
+     * Sets up the object.
+     */
+    @Before
+    public void setUp() {
+        request = createMock(Request.class);
+        expect(request.getAvailableScopes()).andReturn(
+                Arrays.asList(new String[]{"request", "session", "application"})).anyTimes();
+        TilesRequestContextHolder holder = new TilesRequestContextHolder();
+        holder.setTilesRequestContext(request);
+        applicationContext = createMock(ApplicationContext.class);
+        factory = new ScopeVariableResolverFactory(holder);
+    }
+
+    /**
+     * Test method for {@link ScopeVariableResolverFactory#isTarget(String)}.
+     */
+    @Test
+    public void testIsTarget() {
+        replay(request, applicationContext);
+        assertFalse(factory.isTarget("header"));
+        assertTrue(factory.isTarget("requestScope"));
+        assertTrue(factory.isTarget("applicationScope"));
+        assertFalse(factory.isTarget("blah"));
+        verify(request, applicationContext);
+    }
+
+    /**
+     * Test method for {@link ScopeVariableResolverFactory#createVariableResolver(String)}.
+     */
+    @Test
+    public void testCreateVariableResolver() {
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+        requestScope.put("one", 1);
+        expect(request.getContext("request")).andReturn(requestScope).times(2);
+        Map<String, Object> applicationScope = new HashMap<String, Object>();
+        applicationScope.put("two", 2);
+        expect(request.getContext("application")).andReturn(applicationScope);
+
+        replay(request, applicationContext);
+        VariableResolver resolver = factory.createVariableResolver("requestScope");
+        assertEquals(0, resolver.getFlags());
+        assertEquals("requestScope", resolver.getName());
+        assertEquals(Map.class, resolver.getType());
+        assertEquals(requestScope, resolver.getValue());
+        resolver.setStaticType(Object.class); // To complete coverage
+        assertEquals(Map.class, resolver.getType());
+        resolver = factory.createVariableResolver("requestScope"); // again to test caching
+        assertEquals(requestScope, resolver.getValue());
+        resolver = factory.createVariableResolver("applicationScope");
+        assertEquals(applicationScope, resolver.getValue());
+        verify(request, applicationContext);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-mvel/src/test/java/org/apache/tiles/mvel/TilesContextBeanVariableResolverFactoryTest.java b/Java-base/tiles/src/tiles-mvel/src/test/java/org/apache/tiles/mvel/TilesContextBeanVariableResolverFactoryTest.java
new file mode 100644
index 000000000..290125e2f
--- /dev/null
+++ b/Java-base/tiles/src/tiles-mvel/src/test/java/org/apache/tiles/mvel/TilesContextBeanVariableResolverFactoryTest.java
@@ -0,0 +1,142 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.mvel;
+
+import java.util.Arrays;
+import static org.easymock.EasyMock.*;
+import static org.junit.Assert.*;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tiles.context.TilesRequestContextHolder;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.Request;
+import org.junit.Before;
+import org.junit.Test;
+import org.mvel2.integration.VariableResolver;
+
+/**
+ * Tests {@link TilesContextBeanVariableResolverFactory}.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public class TilesContextBeanVariableResolverFactoryTest {
+
+    /**
+     * The expected session scope calls.
+     */
+    private static final int EXPECTED_SESSION_CALLS = 3;
+
+    /**
+     * The expected request scope calls.
+     */
+    private static final int EXPECTED_REQUEST_CALLS = 4;
+
+    /**
+     * The Tiles request.
+     */
+    private Request request;
+
+    /**
+     * The Tiles application context.
+     */
+    private ApplicationContext applicationContext;
+
+    /**
+     * The object to test.
+     */
+    private TilesContextBeanVariableResolverFactory factory;
+
+    /**
+     * Sets up the object.
+     */
+    @Before
+    public void setUp() {
+        request = createMock(Request.class);
+        TilesRequestContextHolder holder = new TilesRequestContextHolder();
+        holder.setTilesRequestContext(request);
+        applicationContext = createMock(ApplicationContext.class);
+        factory = new TilesContextBeanVariableResolverFactory(holder);
+    }
+
+    /**
+     * Test method for {@link TilesContextBeanVariableResolverFactory#createVariableResolver(String)}.
+     */
+    @Test
+    public void testCreateVariableResolver() {
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+        requestScope.put("one", 1);
+        expect(request.getContext("request")).andReturn(requestScope).anyTimes();
+        Map<String, Object> applicationScope = new HashMap<String, Object>();
+        applicationScope.put("two", 2);
+        Map<String, Object> sessionScope = new HashMap<String, Object>();
+        sessionScope.put("three", "three");
+        expect(request.getContext("session")).andReturn(sessionScope).anyTimes();
+        expect(request.getAvailableScopes()).andReturn(
+                Arrays.asList(new String[] { "request", "session", "application" }))
+                .anyTimes();
+        expect(request.getContext("application")).andReturn(applicationScope).anyTimes();
+        replay(request, applicationContext);
+
+        VariableResolver resolver = factory.createVariableResolver("one");
+        assertEquals(1, resolver.getValue());
+        assertEquals(Integer.class, resolver.getType());
+        resolver = factory.createVariableResolver("two");
+        assertEquals(2, resolver.getValue());
+        resolver = factory.createVariableResolver("three");
+        assertEquals("three", resolver.getValue());
+        resolver = factory.createVariableResolver("four");
+        assertEquals(Object.class, resolver.getType());
+        assertNull(resolver.getValue());
+        verify(request, applicationContext);
+    }
+
+    /**
+     * Test method for {@link TilesContextBeanVariableResolverFactory#isTarget(String)}.
+     */
+    @Test
+    public void testIsTarget() {
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+        requestScope.put("one", 1);
+        expect(request.getContext("request")).andReturn(requestScope).times(
+                EXPECTED_REQUEST_CALLS);
+        Map<String, Object> applicationScope = new HashMap<String, Object>();
+        applicationScope.put("two", 2);
+        Map<String, Object> sessionScope = new HashMap<String, Object>();
+        sessionScope.put("three", "three");
+        expect(request.getContext("session")).andReturn(sessionScope).times(
+                EXPECTED_SESSION_CALLS);
+        expect(request.getAvailableScopes()).andReturn(
+                Arrays.asList(new String[] { "request", "session", "application" }))
+                .anyTimes();
+        expect(request.getContext("application")).andReturn(applicationScope).anyTimes();
+        replay(request, applicationContext);
+
+        assertTrue(factory.isTarget("one"));
+        assertTrue(factory.isTarget("two"));
+        assertTrue(factory.isTarget("three"));
+        assertFalse(factory.isTarget("four"));
+        verify(request, applicationContext);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-mvel/src/test/java/org/apache/tiles/mvel/TilesContextVariableResolverFactoryTest.java b/Java-base/tiles/src/tiles-mvel/src/test/java/org/apache/tiles/mvel/TilesContextVariableResolverFactoryTest.java
new file mode 100644
index 000000000..0c2219dc2
--- /dev/null
+++ b/Java-base/tiles/src/tiles-mvel/src/test/java/org/apache/tiles/mvel/TilesContextVariableResolverFactoryTest.java
@@ -0,0 +1,118 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.mvel;
+
+import static org.junit.Assert.*;
+import static org.easymock.EasyMock.*;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tiles.context.TilesRequestContextHolder;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.Request;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mvel2.integration.VariableResolver;
+
+/**
+ * Tests {@link TilesContextVariableResolverFactory}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TilesContextVariableResolverFactoryTest {
+
+    /**
+     * The Tiles request.
+     */
+    private Request request;
+
+    /**
+     * The Tiles application context.
+     */
+    private ApplicationContext applicationContext;
+
+    /**
+     * The object to test.
+     */
+    private TilesContextVariableResolverFactory factory;
+
+    /**
+     * Sets up the object.
+     */
+    @Before
+    public void setUp() {
+        request = createMock(Request.class);
+        TilesRequestContextHolder holder = new TilesRequestContextHolder();
+        holder.setTilesRequestContext(request);
+        applicationContext = createMock(ApplicationContext.class);
+        factory = new TilesContextVariableResolverFactory(holder);
+    }
+
+    /**
+     * Tears down the object.
+     */
+    @After
+    public void tearDown() {
+        verify(request, applicationContext);
+    }
+
+    /**
+     * Test method for {@link TilesContextVariableResolverFactory#isTarget(String)}.
+     */
+    @Test
+    public void testIsTarget() {
+        replay(request, applicationContext);
+        assertTrue(factory.isTarget("header"));
+        assertFalse(factory.isTarget("requestScope"));
+        assertTrue(factory.isTarget("applicationScope"));
+        assertFalse(factory.isTarget("blah"));
+    }
+
+    /**
+     * Test method for {@link TilesContextVariableResolverFactory#createVariableResolver(String)}.
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testCreateVariableResolver() {
+        Map<String, String> header = createMock(Map.class);
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+        requestScope.put("one", 1);
+        Map<String, Object> applicationScope = new HashMap<String, Object>();
+        applicationScope.put("two", 2);
+
+        expect(request.getApplicationContext()).andReturn(applicationContext);
+        expect(applicationContext.getApplicationScope()).andReturn(applicationScope);
+        expect(request.getHeader()).andReturn(header);
+
+        replay(request, applicationContext, header);
+
+        VariableResolver resolver = factory.createVariableResolver("header");
+        assertEquals(Map.class, resolver.getType());
+        assertEquals(header, resolver.getValue());
+        resolver = factory.createVariableResolver("applicationScope");
+        assertEquals(applicationScope, resolver.getValue());
+        assertEquals(Map.class, resolver.getType());
+        verify(header);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-ognl/pom.xml b/Java-base/tiles/src/tiles-ognl/pom.xml
new file mode 100644
index 000000000..3c3387ed0
--- /dev/null
+++ b/Java-base/tiles/src/tiles-ognl/pom.xml
@@ -0,0 +1,119 @@
+<?xml version="1.0"?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+  <parent>
+    <groupId>org.apache.tiles</groupId>
+    <artifactId>tiles-parent</artifactId>
+    <version>3.1-SNAPSHOT</version>
+  </parent>
+
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>tiles-ognl</artifactId>
+  <packaging>jar</packaging>
+  <name>Tiles - OGNL support</name>
+  <description>Tiles OGNL support: Classes and tag libraries to use OGNL as an expression language in attribute expressions.</description>
+
+  <properties>
+  	<tiles.osgi.symbolicName>org.apache.tiles.ognl</tiles.osgi.symbolicName>
+  </properties>
+
+  <build>
+    <resources>
+      <resource>
+        <directory>src/main/resources</directory>
+        <excludes>
+          <exclude>LICENSE.txt</exclude>
+          <exclude>NOTICE.txt</exclude>
+        </excludes>
+      </resource>
+      <resource>
+        <directory>src/main/resources</directory>
+        <includes>
+          <include>LICENSE.txt</include>
+          <include>NOTICE.txt</include>
+        </includes>
+        <targetPath>META-INF</targetPath>
+      </resource>
+    </resources>
+
+    <plugins>
+      <plugin>
+        <artifactId>maven-jar-plugin</artifactId>
+        <configuration>
+          <archive>
+            <manifest>
+            </manifest>
+          </archive>
+        </configuration>
+      </plugin>
+    </plugins>
+
+  </build>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.tiles</groupId>
+      <artifactId>tiles-core</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>jcl-over-slf4j</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-jdk14</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.easymock</groupId>
+      <artifactId>easymock</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.easymock</groupId>
+      <artifactId>easymockclassextension</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>ognl</groupId>
+      <artifactId>ognl</artifactId>
+    </dependency>
+  </dependencies>
+
+</project>
diff --git a/Java-base/tiles/src/tiles-ognl/src/main/java/org/apache/tiles/ognl/AnyScopePropertyAccessor.java b/Java-base/tiles/src/tiles-ognl/src/main/java/org/apache/tiles/ognl/AnyScopePropertyAccessor.java
new file mode 100644
index 000000000..e572f6af0
--- /dev/null
+++ b/Java-base/tiles/src/tiles-ognl/src/main/java/org/apache/tiles/ognl/AnyScopePropertyAccessor.java
@@ -0,0 +1,97 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.ognl;
+
+import java.util.Map;
+
+import ognl.OgnlContext;
+import ognl.PropertyAccessor;
+
+import org.apache.tiles.request.Request;
+
+/**
+ * Accesses attributes in any scope.
+ *
+ * @version $Rev$ $Date$
+ */
+public class AnyScopePropertyAccessor implements PropertyAccessor {
+
+    @Override
+    public Object getProperty(@SuppressWarnings("rawtypes") Map context, Object target, Object name) {
+        Request request = (Request) target;
+        String attributeName = (String) name;
+        for (String scopeName : request.getAvailableScopes()) {
+            Map<String, Object> scope = request.getContext(scopeName);
+            if (scope.containsKey(attributeName)) {
+                return scope.get(attributeName);
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public String getSourceAccessor(OgnlContext context, Object target,
+            Object index) {
+        Request request = (Request) target;
+        String attributeName = (String) index;
+        for (String scopeName : request.getAvailableScopes()) {
+            Map<String, Object> scope = request.getContext(scopeName);
+            if (scope.containsKey(attributeName)) {
+                return ".getContext(\"" + scopeName + "\").get(index)";
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public String getSourceSetter(OgnlContext context, Object target,
+            Object index) {
+        Request request = (Request) target;
+        String attributeName = (String) index;
+        String[] availableScopes = request.getAvailableScopes().toArray(new String[0]);
+        for (String scopeName : availableScopes) {
+            Map<String, Object> scope = request.getContext(scopeName);
+            if (scope.containsKey(attributeName)) {
+                return ".getContext(\"" + scopeName + "\").put(index, target)";
+            }
+        }
+        return ".getContext(\"" + availableScopes[0] + "\").put(index, target)";
+    }
+
+    @Override
+    public void setProperty(@SuppressWarnings("rawtypes") Map context, Object target, Object name,
+            Object value) {
+        Request request = (Request) target;
+        String attributeName = (String) name;
+        String[] availableScopes = request.getAvailableScopes().toArray(new String[0]);
+        for (String scopeName : availableScopes) {
+            Map<String, Object> scope = request.getContext(scopeName);
+            if (scope.containsKey(attributeName)) {
+                scope.put(attributeName, value);
+                return;
+            }
+        }
+        if (availableScopes.length > 0) {
+            request.getContext(availableScopes[0]).put(attributeName, value);
+        }
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-ognl/src/main/java/org/apache/tiles/ognl/DelegatePropertyAccessor.java b/Java-base/tiles/src/tiles-ognl/src/main/java/org/apache/tiles/ognl/DelegatePropertyAccessor.java
new file mode 100644
index 000000000..60175e035
--- /dev/null
+++ b/Java-base/tiles/src/tiles-ognl/src/main/java/org/apache/tiles/ognl/DelegatePropertyAccessor.java
@@ -0,0 +1,88 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.ognl;
+
+import java.util.Map;
+
+import ognl.OgnlContext;
+import ognl.OgnlException;
+import ognl.PropertyAccessor;
+
+/**
+ * Uses a {@link PropertyAccessorDelegateFactory} to delegate the methods to
+ * another {@link PropertyAccessor}.
+ *
+ * @param <T> The type of the accessed root object.
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public class DelegatePropertyAccessor<T> implements PropertyAccessor {
+
+    /**
+     * The property accessor factory.
+     *
+     * @since 2.2.0
+     */
+    private PropertyAccessorDelegateFactory<T> factory;
+
+    /**
+     * Constructor.
+     *
+     * @param factory The property accessor factory.
+     * @since 2.2.0
+     */
+    public DelegatePropertyAccessor(PropertyAccessorDelegateFactory<T> factory) {
+        this.factory = factory;
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
+    public Object getProperty(@SuppressWarnings("rawtypes") Map context, Object target, Object name)
+            throws OgnlException {
+        return factory.getPropertyAccessor((String) name, (T) target).getProperty(
+                context, target, name);
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
+    public void setProperty(@SuppressWarnings("rawtypes") Map context, Object target, Object name,
+            Object value) throws OgnlException {
+        factory.getPropertyAccessor((String) name, (T) target).setProperty(context,
+                target, name, value);
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
+    public String getSourceAccessor(OgnlContext context, Object target,
+            Object index) {
+        return factory.getPropertyAccessor((String) index, (T) target)
+                .getSourceAccessor(context, target, index);
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
+    public String getSourceSetter(OgnlContext context, Object target,
+            Object index) {
+        return factory.getPropertyAccessor((String) index, (T) target)
+                .getSourceSetter(context, target, index);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-ognl/src/main/java/org/apache/tiles/ognl/NestedObjectDelegatePropertyAccessor.java b/Java-base/tiles/src/tiles-ognl/src/main/java/org/apache/tiles/ognl/NestedObjectDelegatePropertyAccessor.java
new file mode 100644
index 000000000..2d9b50c45
--- /dev/null
+++ b/Java-base/tiles/src/tiles-ognl/src/main/java/org/apache/tiles/ognl/NestedObjectDelegatePropertyAccessor.java
@@ -0,0 +1,101 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.ognl;
+
+import java.util.Map;
+
+import ognl.OgnlContext;
+import ognl.OgnlException;
+import ognl.PropertyAccessor;
+
+/**
+ * Uses a {@link PropertyAccessor} as a delegate, but passing a nested object as
+ * target.
+ *
+ * @param <T> The root object type from which the target object will be
+ * extracted.
+ * @since 2.2.0
+ * @version $Rev$ $Date$
+ */
+public class NestedObjectDelegatePropertyAccessor<T> implements
+        PropertyAccessor {
+
+    /**
+     * The extractor of the nested object.
+     *
+     * @since 2.2.0
+     */
+    private NestedObjectExtractor<T> nestedObjectExtractor;
+
+    /**
+     * The delegated property accessor.
+     *
+     * @since 2.2.0
+     */
+    private PropertyAccessor propertyAccessor;
+
+    /**
+     * Constructor.
+     *
+     * @param nestedObjectExtractor The extractor of the nested object.
+     * @param propertyAccessor The delegated property accessor.
+     * @since 2.2.0
+     */
+    public NestedObjectDelegatePropertyAccessor(
+            NestedObjectExtractor<T> nestedObjectExtractor,
+            PropertyAccessor propertyAccessor) {
+        this.nestedObjectExtractor = nestedObjectExtractor;
+        this.propertyAccessor = propertyAccessor;
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
+    public Object getProperty(@SuppressWarnings("rawtypes") Map context, Object target, Object name)
+            throws OgnlException {
+        return propertyAccessor.getProperty(context, nestedObjectExtractor
+                .getNestedObject((T) target), name);
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
+    public void setProperty(@SuppressWarnings("rawtypes") Map context, Object target, Object name,
+            Object value) throws OgnlException {
+        propertyAccessor.setProperty(context, nestedObjectExtractor
+                .getNestedObject((T) target), name, value);
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
+    public String getSourceAccessor(OgnlContext context, Object target,
+            Object index) {
+        return propertyAccessor.getSourceAccessor(context,
+                nestedObjectExtractor.getNestedObject((T) target), index);
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
+    public String getSourceSetter(OgnlContext context, Object target,
+            Object index) {
+        return propertyAccessor.getSourceSetter(context, nestedObjectExtractor
+                .getNestedObject((T) target), index);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-ognl/src/main/java/org/apache/tiles/ognl/NestedObjectExtractor.java b/Java-base/tiles/src/tiles-ognl/src/main/java/org/apache/tiles/ognl/NestedObjectExtractor.java
new file mode 100644
index 000000000..c6888f43c
--- /dev/null
+++ b/Java-base/tiles/src/tiles-ognl/src/main/java/org/apache/tiles/ognl/NestedObjectExtractor.java
@@ -0,0 +1,41 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.ognl;
+
+/**
+ * Extracts an object using another object as a basis.
+ *
+ * @param <T> The type of the root object.
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public interface NestedObjectExtractor<T> {
+
+    /**
+     * Extracts the nested object.
+     *
+     * @param obj The root object.
+     * @return The extracted nested object.
+     * @since 2.2.0
+     */
+    Object getNestedObject(T obj);
+}
diff --git a/Java-base/tiles/src/tiles-ognl/src/main/java/org/apache/tiles/ognl/OGNLAttributeEvaluator.java b/Java-base/tiles/src/tiles-ognl/src/main/java/org/apache/tiles/ognl/OGNLAttributeEvaluator.java
new file mode 100644
index 000000000..ee4d8968b
--- /dev/null
+++ b/Java-base/tiles/src/tiles-ognl/src/main/java/org/apache/tiles/ognl/OGNLAttributeEvaluator.java
@@ -0,0 +1,51 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.ognl;
+
+import ognl.Ognl;
+import ognl.OgnlException;
+
+import org.apache.tiles.evaluator.AbstractAttributeEvaluator;
+import org.apache.tiles.evaluator.EvaluationException;
+import org.apache.tiles.request.Request;
+
+/**
+ * Evaluates attribute expressions and expressions with OGNL language.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public class OGNLAttributeEvaluator extends AbstractAttributeEvaluator {
+
+    /** {@inheritDoc} */
+    public Object evaluate(String expression, Request request) {
+        if (expression == null) {
+            throw new IllegalArgumentException("The expression parameter cannot be null");
+        }
+        try {
+            return Ognl.getValue(expression, request);
+        } catch (OgnlException e) {
+            throw new EvaluationException("Cannot evaluate OGNL expression '"
+                    + expression + "'", e);
+        }
+    }
+}
diff --git a/Java-base/tiles/src/tiles-ognl/src/main/java/org/apache/tiles/ognl/PropertyAccessorDelegateFactory.java b/Java-base/tiles/src/tiles-ognl/src/main/java/org/apache/tiles/ognl/PropertyAccessorDelegateFactory.java
new file mode 100644
index 000000000..7c619ca9b
--- /dev/null
+++ b/Java-base/tiles/src/tiles-ognl/src/main/java/org/apache/tiles/ognl/PropertyAccessorDelegateFactory.java
@@ -0,0 +1,46 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.ognl;
+
+import ognl.PropertyAccessor;
+
+/**
+ * Decides a {@link PropertyAccessor} depending on the property name and the
+ * object to evaluate.
+ *
+ * @param <T> The type of the root object to evaluate.
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public interface PropertyAccessorDelegateFactory<T> {
+
+    /**
+     * Returns a prooerty accessor appropriate for the property name and the
+     * object passed.
+     *
+     * @param propertyName The name of the property.
+     * @param obj The root object to evaluate.
+     * @return The appropriate property accessor.
+     * @since 2.2.0
+     */
+    PropertyAccessor getPropertyAccessor(String propertyName, T obj);
+}
diff --git a/Java-base/tiles/src/tiles-ognl/src/main/java/org/apache/tiles/ognl/ScopePropertyAccessor.java b/Java-base/tiles/src/tiles-ognl/src/main/java/org/apache/tiles/ognl/ScopePropertyAccessor.java
new file mode 100644
index 000000000..35f47fe83
--- /dev/null
+++ b/Java-base/tiles/src/tiles-ognl/src/main/java/org/apache/tiles/ognl/ScopePropertyAccessor.java
@@ -0,0 +1,76 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.ognl;
+
+import java.util.Map;
+
+import ognl.OgnlContext;
+import ognl.PropertyAccessor;
+
+import org.apache.tiles.request.Request;
+
+/**
+ * Accesses a scope.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ScopePropertyAccessor implements PropertyAccessor {
+
+    /**
+     * The length of the scope suffix: "Scope".
+     */
+    static final int SCOPE_SUFFIX_LENGTH = 5;
+
+    @Override
+    public Object getProperty(@SuppressWarnings("rawtypes") Map context, Object target, Object name) {
+        Request request = (Request) target;
+        String scope = (String) name;
+        if (scope.endsWith("Scope")) {
+            String scopeName = scope.substring(0, scope.length() - SCOPE_SUFFIX_LENGTH);
+            return request.getContext(scopeName);
+        }
+        return null;
+    }
+
+    @Override
+    public String getSourceAccessor(OgnlContext context, Object target,
+            Object index) {
+        String scope = (String) index;
+        if (scope.endsWith("Scope")) {
+            String scopeName = scope.substring(0, scope.length() - SCOPE_SUFFIX_LENGTH);
+            return ".getContext(\"" + scopeName + "\")";
+        }
+        return null;
+    }
+
+    @Override
+    public String getSourceSetter(OgnlContext context, Object target,
+            Object index) {
+        return null;
+    }
+
+    @Override
+    public void setProperty(@SuppressWarnings("rawtypes") Map context, Object target, Object name,
+            Object value) {
+        // Does nothing.
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-ognl/src/main/java/org/apache/tiles/ognl/TilesApplicationContextNestedObjectExtractor.java b/Java-base/tiles/src/tiles-ognl/src/main/java/org/apache/tiles/ognl/TilesApplicationContextNestedObjectExtractor.java
new file mode 100644
index 000000000..7642fa825
--- /dev/null
+++ b/Java-base/tiles/src/tiles-ognl/src/main/java/org/apache/tiles/ognl/TilesApplicationContextNestedObjectExtractor.java
@@ -0,0 +1,40 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.ognl;
+
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.Request;
+
+/**
+ * Extracts the application context from a Tiles request.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public class TilesApplicationContextNestedObjectExtractor implements
+        NestedObjectExtractor<Request> {
+
+    /** {@inheritDoc} */
+    public ApplicationContext getNestedObject(Request obj) {
+        return obj.getApplicationContext();
+    }
+}
diff --git a/Java-base/tiles/src/tiles-ognl/src/main/java/org/apache/tiles/ognl/TilesContextPropertyAccessorDelegateFactory.java b/Java-base/tiles/src/tiles-ognl/src/main/java/org/apache/tiles/ognl/TilesContextPropertyAccessorDelegateFactory.java
new file mode 100644
index 000000000..a253f44b8
--- /dev/null
+++ b/Java-base/tiles/src/tiles-ognl/src/main/java/org/apache/tiles/ognl/TilesContextPropertyAccessorDelegateFactory.java
@@ -0,0 +1,112 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.ognl;
+
+import ognl.PropertyAccessor;
+
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.Request;
+import org.apache.tiles.util.CombinedBeanInfo;
+
+/**
+ * Decides the appropriate {@link PropertyAccessor} for the given property name
+ * and {@link Request}.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public class TilesContextPropertyAccessorDelegateFactory implements
+        PropertyAccessorDelegateFactory<Request> {
+
+    /**
+     * The plain object property accessor, to be used directly for
+     * {@link Request}.
+     */
+    private PropertyAccessor objectPropertyAccessor;
+
+    /**
+     * The application context property accessor.
+     */
+    private PropertyAccessor applicationContextPropertyAccessor;
+
+    /**
+     * The request scope property accessor.
+     */
+    private PropertyAccessor anyScopePropertyAccessor;
+
+    /**
+     * The session scope property accessor.
+     */
+    private PropertyAccessor scopePropertyAccessor;
+
+    /**
+     * The bean info of {@link Request} and
+     * {@link org.apache.tiles.request.ApplicationContext}.
+     */
+    private CombinedBeanInfo beanInfo;
+
+    /**
+     * Constructor.
+     *
+     * @param objectPropertyAccessor The plain object property accessor, to be
+     * used directly for {@link Request}.
+     * @param applicationContextPropertyAccessor The application context
+     * property accessor.
+     * @param anyScopePropertyAccessor The request scope property accessor.
+     * @param scopePropertyAccessor The session scope property accessor.
+     * @since 2.2.0
+     */
+    public TilesContextPropertyAccessorDelegateFactory(
+            PropertyAccessor objectPropertyAccessor,
+            PropertyAccessor applicationContextPropertyAccessor,
+            PropertyAccessor anyScopePropertyAccessor,
+            PropertyAccessor scopePropertyAccessor) {
+        beanInfo = new CombinedBeanInfo(Request.class, ApplicationContext.class);
+        this.objectPropertyAccessor = objectPropertyAccessor;
+        this.applicationContextPropertyAccessor = applicationContextPropertyAccessor;
+        this.anyScopePropertyAccessor = anyScopePropertyAccessor;
+        this.scopePropertyAccessor = scopePropertyAccessor;
+    }
+
+    /** {@inheritDoc} */
+    public PropertyAccessor getPropertyAccessor(String propertyName,
+            Request request) {
+        PropertyAccessor retValue;
+        if (propertyName.endsWith("Scope")) {
+            String scopeName = propertyName.substring(0, propertyName.length()
+                    - ScopePropertyAccessor.SCOPE_SUFFIX_LENGTH);
+            if (request.getContext(scopeName) != null) {
+                return scopePropertyAccessor;
+            }
+        }
+        if (beanInfo.getMappedDescriptors(Request.class)
+                .containsKey(propertyName)) {
+            retValue = objectPropertyAccessor;
+        } else if (beanInfo.getMappedDescriptors(ApplicationContext.class)
+                .containsKey(propertyName)) {
+            retValue = applicationContextPropertyAccessor;
+        } else {
+            return anyScopePropertyAccessor;
+        }
+        return retValue;
+    }
+}
diff --git a/Java-base/tiles/src/tiles-ognl/src/main/java/org/apache/tiles/ognl/package-info.java b/Java-base/tiles/src/tiles-ognl/src/main/java/org/apache/tiles/ognl/package-info.java
new file mode 100644
index 000000000..116082cdd
--- /dev/null
+++ b/Java-base/tiles/src/tiles-ognl/src/main/java/org/apache/tiles/ognl/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * $Id$
+ *
+ * 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.
+ */
+/**
+ * Attribute evaluator classes that can perform OGNL evaluation for attributes.
+ */
+package org.apache.tiles.ognl;
diff --git a/Java-base/tiles/src/tiles-ognl/src/site/site.xml b/Java-base/tiles/src/tiles-ognl/src/site/site.xml
new file mode 100644
index 000000000..df764fb47
--- /dev/null
+++ b/Java-base/tiles/src/tiles-ognl/src/site/site.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<project name="Apache Tiles - OGNL Support">
+     <skin>
+        <groupId>org.apache.maven.skins</groupId>
+        <artifactId>maven-fluido-skin</artifactId>
+        <version>1.3.0</version>
+     </skin>
+     <custom>
+        <fluidoSkin>
+        <topBarEnabled>true</topBarEnabled>
+        <sideBarEnabled>false</sideBarEnabled>
+        <searchEnabled>true</searchEnabled>
+        <gitHub>
+            <projectId>apache/tiles</projectId>
+            <ribbonOrientation>right</ribbonOrientation>
+            <ribbonColor>darkblue</ribbonColor>
+        </gitHub>
+        </fluidoSkin>
+     </custom>
+    <bannerLeft>
+        <name>Apache Tiles&#8482;</name>
+        <src>http://tiles.apache.org/images/logo.png</src>
+        <href>http://tiles.apache.org</href>
+    </bannerLeft>
+    <bannerRight>
+        <name>Apache Software Foundation</name>
+        <src>http://struts.apache.org/images/asf-logo.gif</src>
+        <href>http://www.apache.org</href>
+    </bannerRight>
+    <body>
+
+        <menu name="Apache Tiles&#8482;">
+            <item
+                   name="Welcome"
+                   href="../../index.html"/>
+            <item
+                    name="Tiles 3.0.x"
+                    href="../../framework/index.html"/>
+            <item
+                    name="Autotag 1.0.x"
+                    href="../../tiles-autotag/index.html"/>
+            <item
+                    name="Request 1.0.x"
+                    href="../../tiles-request/index.html"/>
+            <item
+                   name="Security bulletins"
+                   href="../security/index.html"/>
+            <item
+                   name="Download"
+                   href="http://tiles.apache.org/download.html"/>
+        </menu>
+
+        <menu ref="modules" />
+        <menu ref="reports" />
+
+        <footer>
+            <div class="row span12">
+                Apache Tiles, Tiles, Apache, the Apache feather logo, and the Apache Tiles
+                project logos are trademarks of The Apache Software Foundation.
+            </div>
+        </footer>
+    </body>
+</project>
diff --git a/Java-base/tiles/src/tiles-ognl/src/test/java/org/apache/tiles/ognl/AnyScopePropertyAccessorTest.java b/Java-base/tiles/src/tiles-ognl/src/test/java/org/apache/tiles/ognl/AnyScopePropertyAccessorTest.java
new file mode 100644
index 000000000..fb60fac2b
--- /dev/null
+++ b/Java-base/tiles/src/tiles-ognl/src/test/java/org/apache/tiles/ognl/AnyScopePropertyAccessorTest.java
@@ -0,0 +1,162 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.ognl;
+
+import java.util.Arrays;
+import static org.easymock.classextension.EasyMock.*;
+import static org.junit.Assert.*;
+
+import java.util.Map;
+
+import org.apache.tiles.request.Request;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests {@link AnyScopePropertyAccessor}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class AnyScopePropertyAccessorTest {
+
+    /**
+     * The accessor to test.
+     */
+    private AnyScopePropertyAccessor accessor;
+
+    /**
+     * Sets up the test.
+     */
+    @Before
+    public void setUp() {
+        accessor = new AnyScopePropertyAccessor();
+    }
+
+    /**
+     * Test method for {@link AnyScopePropertyAccessor#getProperty(java.util.Map, java.lang.Object, java.lang.Object)}.
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testGetProperty() {
+        Request request = createMock(Request.class);
+        Map<String, Object> oneScope = createMock(Map.class);
+        Map<String, Object> twoScope = createMock(Map.class);
+
+        expect(request.getAvailableScopes()).andReturn(Arrays.asList(new String[] {"one", "two"})).anyTimes();
+        expect(request.getContext("one")).andReturn(oneScope).anyTimes();
+        expect(request.getContext("two")).andReturn(twoScope).anyTimes();
+        expect(oneScope.containsKey("name1")).andReturn(true);
+        expect(oneScope.get("name1")).andReturn("value1");
+        expect(oneScope.containsKey("name2")).andReturn(false);
+        expect(oneScope.containsKey("name3")).andReturn(false);
+        expect(twoScope.containsKey("name2")).andReturn(true);
+        expect(twoScope.get("name2")).andReturn("value2");
+        expect(twoScope.containsKey("name3")).andReturn(false);
+
+        replay(request, oneScope, twoScope);
+        assertEquals("value1", accessor.getProperty(null, request, "name1"));
+        assertEquals("value2", accessor.getProperty(null, request, "name2"));
+        assertNull(accessor.getProperty(null, request, "name3"));
+        verify(request, oneScope, twoScope);
+    }
+
+    /**
+     * Test method for {@link AnyScopePropertyAccessor#getSourceAccessor(OgnlContext, Object, Object)}.
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testGetSourceAccessor() {
+        Request request = createMock(Request.class);
+        Map<String, Object> oneScope = createMock(Map.class);
+        Map<String, Object> twoScope = createMock(Map.class);
+
+        expect(request.getAvailableScopes()).andReturn(Arrays.asList(new String[] {"one", "two"})).anyTimes();
+        expect(request.getContext("one")).andReturn(oneScope).anyTimes();
+        expect(request.getContext("two")).andReturn(twoScope).anyTimes();
+        expect(oneScope.containsKey("name1")).andReturn(true);
+        expect(oneScope.containsKey("name2")).andReturn(false);
+        expect(oneScope.containsKey("name3")).andReturn(false);
+        expect(twoScope.containsKey("name2")).andReturn(true);
+        expect(twoScope.containsKey("name3")).andReturn(false);
+
+        replay(request, oneScope, twoScope);
+        assertEquals(".getContext(\"one\").get(index)", accessor.getSourceAccessor(null, request, "name1"));
+        assertEquals(".getContext(\"two\").get(index)", accessor.getSourceAccessor(null, request, "name2"));
+        assertNull(accessor.getSourceAccessor(null, request, "name3"));
+        verify(request, oneScope, twoScope);
+    }
+
+    /**
+     * Test method for {@link AnyScopePropertyAccessor#getSourceSetter(OgnlContext, Object, Object)}.
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testGetSourceSetter() {
+        Request request = createMock(Request.class);
+        Map<String, Object> oneScope = createMock(Map.class);
+        Map<String, Object> twoScope = createMock(Map.class);
+
+        expect(request.getAvailableScopes()).andReturn(Arrays.asList(new String[] {"one", "two"})).anyTimes();
+        expect(request.getContext("one")).andReturn(oneScope).anyTimes();
+        expect(request.getContext("two")).andReturn(twoScope).anyTimes();
+        expect(oneScope.containsKey("name1")).andReturn(true);
+        expect(oneScope.containsKey("name2")).andReturn(false);
+        expect(oneScope.containsKey("name3")).andReturn(false);
+        expect(twoScope.containsKey("name2")).andReturn(true);
+        expect(twoScope.containsKey("name3")).andReturn(false);
+
+        replay(request, oneScope, twoScope);
+        assertEquals(".getContext(\"one\").put(index, target)", accessor.getSourceSetter(null, request, "name1"));
+        assertEquals(".getContext(\"two\").put(index, target)", accessor.getSourceSetter(null, request, "name2"));
+        assertEquals(".getContext(\"one\").put(index, target)", accessor.getSourceSetter(null, request, "name3"));
+        verify(request, oneScope, twoScope);
+    }
+
+    /**
+     * Test method for {@link AnyScopePropertyAccessor#setProperty(Map, Object, Object, Object)}.
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testSetProperty() {
+        Request request = createMock(Request.class);
+        Map<String, Object> oneScope = createMock(Map.class);
+        Map<String, Object> twoScope = createMock(Map.class);
+
+        expect(request.getAvailableScopes()).andReturn(Arrays.asList(new String[] {"one", "two"})).anyTimes();
+        expect(request.getContext("one")).andReturn(oneScope).anyTimes();
+        expect(request.getContext("two")).andReturn(twoScope).anyTimes();
+        expect(oneScope.containsKey("name1")).andReturn(true);
+        expect(oneScope.put("name1", "otherValue1")).andReturn("value1");
+        expect(oneScope.containsKey("name2")).andReturn(false);
+        expect(oneScope.containsKey("name3")).andReturn(false);
+        expect(twoScope.containsKey("name2")).andReturn(true);
+        expect(twoScope.put("name2", "otherValue2")).andReturn("value2");
+        expect(twoScope.containsKey("name3")).andReturn(false);
+        expect(oneScope.put("name3", "otherValue3")).andReturn(null);
+
+        replay(request, oneScope, twoScope);
+        accessor.setProperty(null, request, "name1", "otherValue1");
+        accessor.setProperty(null, request, "name2", "otherValue2");
+        accessor.setProperty(null, request, "name3", "otherValue3");
+        verify(request, oneScope, twoScope);
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-ognl/src/test/java/org/apache/tiles/ognl/DelegatePropertyAccessorTest.java b/Java-base/tiles/src/tiles-ognl/src/test/java/org/apache/tiles/ognl/DelegatePropertyAccessorTest.java
new file mode 100644
index 000000000..bcf9a74ef
--- /dev/null
+++ b/Java-base/tiles/src/tiles-ognl/src/test/java/org/apache/tiles/ognl/DelegatePropertyAccessorTest.java
@@ -0,0 +1,115 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.ognl;
+
+import static org.junit.Assert.*;
+import static org.easymock.classextension.EasyMock.*;
+
+import java.util.Map;
+
+import ognl.OgnlContext;
+import ognl.OgnlException;
+import ognl.PropertyAccessor;
+
+import org.junit.Test;
+
+/**
+ * Tests {@link DelegatePropertyAccessor}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class DelegatePropertyAccessorTest {
+
+    /**
+     * Test method for {@link DelegatePropertyAccessor#getProperty(java.util.Map, Object, Object)}.
+     * @throws OgnlException If something goes wrong.
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testGetProperty() throws OgnlException {
+        PropertyAccessorDelegateFactory<Integer> factory = createMock(PropertyAccessorDelegateFactory.class);
+        PropertyAccessor mockAccessor = createMock(PropertyAccessor.class);
+        Map<String, Object> context = createMock(Map.class);
+        expect(factory.getPropertyAccessor("property", 1)).andReturn(mockAccessor);
+        expect(mockAccessor.getProperty(context, 1, "property")).andReturn("value");
+
+        replay(factory, mockAccessor, context);
+        PropertyAccessor accessor = new DelegatePropertyAccessor<Integer>(factory);
+        assertEquals("value", accessor.getProperty(context, 1, "property"));
+        verify(factory, mockAccessor, context);
+    }
+
+    /**
+     * Test method for {@link DelegatePropertyAccessor#setProperty(java.util.Map, Object, Object, Object)}.
+     * @throws OgnlException If something goes wrong.
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testSetProperty() throws OgnlException {
+        PropertyAccessorDelegateFactory<Integer> factory = createMock(PropertyAccessorDelegateFactory.class);
+        PropertyAccessor mockAccessor = createMock(PropertyAccessor.class);
+        Map<String, Object> context = createMock(Map.class);
+        expect(factory.getPropertyAccessor("property", 1)).andReturn(mockAccessor);
+        mockAccessor.setProperty(context, 1, "property", "value");
+
+        replay(factory, mockAccessor, context);
+        PropertyAccessor accessor = new DelegatePropertyAccessor<Integer>(factory);
+        accessor.setProperty(context, 1, "property", "value");
+        verify(factory, mockAccessor, context);
+    }
+
+    /**
+     * Test method for {@link DelegatePropertyAccessor#getSourceAccessor(ognl.OgnlContext, Object, Object)}.
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testGetSourceAccessor() {
+        PropertyAccessorDelegateFactory<Integer> factory = createMock(PropertyAccessorDelegateFactory.class);
+        PropertyAccessor mockAccessor = createMock(PropertyAccessor.class);
+        OgnlContext context = createMock(OgnlContext.class);
+        expect(factory.getPropertyAccessor("property", 1)).andReturn(mockAccessor);
+        expect(mockAccessor.getSourceAccessor(context, 1, "property")).andReturn("method");
+
+        replay(factory, mockAccessor, context);
+        PropertyAccessor accessor = new DelegatePropertyAccessor<Integer>(factory);
+        assertEquals("method", accessor.getSourceAccessor(context, 1, "property"));
+        verify(factory, mockAccessor, context);
+    }
+
+    /**
+     * Test method for {@link DelegatePropertyAccessor#getSourceSetter(ognl.OgnlContext, Object, Object)}.
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testGetSourceSetter() {
+        PropertyAccessorDelegateFactory<Integer> factory = createMock(PropertyAccessorDelegateFactory.class);
+        PropertyAccessor mockAccessor = createMock(PropertyAccessor.class);
+        OgnlContext context = createMock(OgnlContext.class);
+        expect(factory.getPropertyAccessor("property", 1)).andReturn(mockAccessor);
+        expect(mockAccessor.getSourceSetter(context, 1, "property")).andReturn("method");
+
+        replay(factory, mockAccessor, context);
+        PropertyAccessor accessor = new DelegatePropertyAccessor<Integer>(factory);
+        assertEquals("method", accessor.getSourceSetter(context, 1, "property"));
+        verify(factory, mockAccessor, context);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-ognl/src/test/java/org/apache/tiles/ognl/NestedObjectDelegatePropertyAccessorTest.java b/Java-base/tiles/src/tiles-ognl/src/test/java/org/apache/tiles/ognl/NestedObjectDelegatePropertyAccessorTest.java
new file mode 100644
index 000000000..293171611
--- /dev/null
+++ b/Java-base/tiles/src/tiles-ognl/src/test/java/org/apache/tiles/ognl/NestedObjectDelegatePropertyAccessorTest.java
@@ -0,0 +1,120 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.ognl;
+
+import static org.junit.Assert.*;
+import static org.easymock.classextension.EasyMock.*;
+
+import java.util.Map;
+
+import ognl.OgnlContext;
+import ognl.OgnlException;
+import ognl.PropertyAccessor;
+
+import org.junit.Test;
+
+/**
+ * Tests {@link NestedObjectDelegatePropertyAccessor}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class NestedObjectDelegatePropertyAccessorTest {
+
+    /**
+     * Test method for {@link NestedObjectDelegatePropertyAccessor#getProperty(java.util.Map, Object, Object)}.
+     * @throws OgnlException If something goes wrong.
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testGetProperty() throws OgnlException {
+        NestedObjectExtractor<Integer> nestedObjectExtractor = createMock(NestedObjectExtractor.class);
+        PropertyAccessor propertyAccessor = createMock(PropertyAccessor.class);
+        Map<String, Object> context = createMock(Map.class);
+        expect(propertyAccessor.getProperty(context, "nested", "property")).andReturn("value");
+        expect(nestedObjectExtractor.getNestedObject(1)).andReturn("nested");
+
+        replay(nestedObjectExtractor, propertyAccessor, context);
+        PropertyAccessor accessor = new NestedObjectDelegatePropertyAccessor<Integer>(
+                nestedObjectExtractor, propertyAccessor);
+        assertEquals("value", accessor.getProperty(context, 1, "property"));
+        verify(nestedObjectExtractor, propertyAccessor, context);
+    }
+
+    /**
+     * Test method for {@link NestedObjectDelegatePropertyAccessor#setProperty(java.util.Map, Object, Object, Object)}.
+     * @throws OgnlException If something goes wrong.
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testSetProperty() throws OgnlException {
+        NestedObjectExtractor<Integer> nestedObjectExtractor = createMock(NestedObjectExtractor.class);
+        PropertyAccessor propertyAccessor = createMock(PropertyAccessor.class);
+        Map<String, Object> context = createMock(Map.class);
+        propertyAccessor.setProperty(context, "nested", "property", "value");
+        expect(nestedObjectExtractor.getNestedObject(1)).andReturn("nested");
+
+        replay(nestedObjectExtractor, propertyAccessor, context);
+        PropertyAccessor accessor = new NestedObjectDelegatePropertyAccessor<Integer>(
+                nestedObjectExtractor, propertyAccessor);
+        accessor.setProperty(context, 1, "property", "value");
+        verify(nestedObjectExtractor, propertyAccessor, context);
+    }
+
+    /**
+     * Test method for {@link NestedObjectDelegatePropertyAccessor#getSourceAccessor(ognl.OgnlContext, Object, Object)}.
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testGetSourceAccessor() {
+        NestedObjectExtractor<Integer> nestedObjectExtractor = createMock(NestedObjectExtractor.class);
+        PropertyAccessor propertyAccessor = createMock(PropertyAccessor.class);
+        OgnlContext context = createMock(OgnlContext.class);
+        expect(propertyAccessor.getSourceAccessor(context, "nested", "property")).andReturn("method");
+        expect(nestedObjectExtractor.getNestedObject(1)).andReturn("nested");
+
+        replay(nestedObjectExtractor, propertyAccessor, context);
+        PropertyAccessor accessor = new NestedObjectDelegatePropertyAccessor<Integer>(
+                nestedObjectExtractor, propertyAccessor);
+        assertEquals("method", accessor.getSourceAccessor(context, 1, "property"));
+        verify(nestedObjectExtractor, propertyAccessor, context);
+    }
+
+    /**
+     * Test method for {@link NestedObjectDelegatePropertyAccessor#getSourceSetter(ognl.OgnlContext, Object, Object)}.
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testGetSourceSetter() {
+        NestedObjectExtractor<Integer> nestedObjectExtractor = createMock(NestedObjectExtractor.class);
+        PropertyAccessor propertyAccessor = createMock(PropertyAccessor.class);
+        OgnlContext context = createMock(OgnlContext.class);
+        expect(propertyAccessor.getSourceSetter(context, "nested", "property")).andReturn("method");
+        expect(nestedObjectExtractor.getNestedObject(1)).andReturn("nested");
+
+        replay(nestedObjectExtractor, propertyAccessor, context);
+        PropertyAccessor accessor = new NestedObjectDelegatePropertyAccessor<Integer>(
+                nestedObjectExtractor, propertyAccessor);
+        assertEquals("method", accessor.getSourceSetter(context, 1, "property"));
+        verify(nestedObjectExtractor, propertyAccessor, context);
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-ognl/src/test/java/org/apache/tiles/ognl/OGNLAttributeEvaluatorTest.java b/Java-base/tiles/src/tiles-ognl/src/test/java/org/apache/tiles/ognl/OGNLAttributeEvaluatorTest.java
new file mode 100644
index 000000000..520b9c482
--- /dev/null
+++ b/Java-base/tiles/src/tiles-ognl/src/test/java/org/apache/tiles/ognl/OGNLAttributeEvaluatorTest.java
@@ -0,0 +1,225 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.ognl;
+
+import java.util.Arrays;
+import static org.easymock.EasyMock.*;
+import static org.easymock.classextension.EasyMock.*;
+import static org.junit.Assert.*;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import ognl.OgnlException;
+import ognl.OgnlRuntime;
+import ognl.PropertyAccessor;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.Expression;
+import org.apache.tiles.evaluator.EvaluationException;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.Request;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests {@link OGNLAttributeEvaluator}.
+ *
+ * @version $Rev$ $Date$$
+ */
+public class OGNLAttributeEvaluatorTest {
+
+    /**
+     * The evaluator to test.
+     */
+    private OGNLAttributeEvaluator evaluator;
+
+    /**
+     * The request object to use.
+     */
+    private Request request;
+
+    /**
+     * The application context.
+     */
+    private ApplicationContext applicationContext;
+
+    /**
+     * Sets up the test.
+     *
+     * @throws OgnlException If something goes wrong.
+     */
+    @Before
+    public void setUp() throws OgnlException {
+        PropertyAccessor objectPropertyAccessor = OgnlRuntime.getPropertyAccessor(Object.class);
+        PropertyAccessor applicationContextPropertyAccessor =
+            new NestedObjectDelegatePropertyAccessor<Request>(
+                new TilesApplicationContextNestedObjectExtractor(),
+                objectPropertyAccessor);
+        PropertyAccessor anyScopePropertyAccessor = new AnyScopePropertyAccessor();
+        PropertyAccessor scopePropertyAccessor = new ScopePropertyAccessor();
+        PropertyAccessorDelegateFactory<Request> factory = new TilesContextPropertyAccessorDelegateFactory(
+                objectPropertyAccessor, applicationContextPropertyAccessor,
+                anyScopePropertyAccessor, scopePropertyAccessor);
+        PropertyAccessor tilesRequestAccessor = new DelegatePropertyAccessor<Request>(factory);
+        OgnlRuntime.setPropertyAccessor(Request.class, tilesRequestAccessor);
+        evaluator = new OGNLAttributeEvaluator();
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+        Map<String, Object> sessionScope = new HashMap<String, Object>();
+        Map<String, Object> applicationScope = new HashMap<String, Object>();
+        requestScope.put("object1", "value");
+        sessionScope.put("object2", new Integer(1));
+        applicationScope.put("object3", new Float(2.0));
+        requestScope.put("paulaBean", new PaulaBean());
+        request = createMock(Request.class);
+        expect(request.getContext("request")).andReturn(requestScope)
+                .anyTimes();
+        expect(request.getContext("session")).andReturn(sessionScope)
+                .anyTimes();
+        expect(request.getContext("application")).andReturn(applicationScope)
+                .anyTimes();
+        expect(request.getAvailableScopes()).andReturn(
+                Arrays.asList(new String[] { "request", "session", "application" })).anyTimes();
+        applicationContext = createMock(ApplicationContext.class);
+        expect(request.getApplicationContext()).andReturn(
+                applicationContext).anyTimes();
+        expect(applicationContext.getApplicationScope()).andReturn(
+                applicationScope).anyTimes();
+        replay(request, applicationContext);
+    }
+
+    /**
+     * Tears down the test.
+     */
+    @After
+    public void tearDown() {
+        verify(request, applicationContext);
+    }
+
+    /**
+     * Tests
+     * {@link OGNLAttributeEvaluator#evaluate(Attribute, Request)}.
+     */
+    @Test
+    public void testEvaluate() {
+        Attribute attribute = new Attribute();
+        attribute.setExpressionObject(new Expression("requestScope.object1"));
+        assertEquals("The value is not correct", "value", evaluator.evaluate(
+                attribute, request));
+        attribute.setExpressionObject(new Expression("sessionScope.object2"));
+        assertEquals("The value is not correct", new Integer(1), evaluator
+                .evaluate(attribute, request));
+        attribute.setExpressionObject(new Expression("applicationScope.object3"));
+        assertEquals("The value is not correct", new Float(2.0), evaluator
+                .evaluate(attribute, request));
+        attribute.setExpressionObject(new Expression("object1"));
+        assertEquals("The value is not correct", "value", evaluator.evaluate(
+                attribute, request));
+        attribute.setExpressionObject(new Expression("object2"));
+        assertEquals("The value is not correct", new Integer(1), evaluator
+                .evaluate(attribute, request));
+        attribute.setExpressionObject(new Expression("object3"));
+        assertEquals("The value is not correct", new Float(2.0), evaluator
+                .evaluate(attribute, request));
+        attribute.setExpressionObject(new Expression("paulaBean.paula"));
+        assertEquals("The value is not correct", "Brillant", evaluator
+                .evaluate(attribute, request));
+        attribute.setExpressionObject(new Expression("'String literal'"));
+        assertEquals("The value is not correct", "String literal", evaluator
+                .evaluate(attribute, request));
+        attribute.setValue(new Integer(2));
+        assertEquals("The value is not correct", new Integer(2), evaluator
+                .evaluate(attribute, request));
+        attribute.setValue("object1");
+        assertEquals("The value has been evaluated", "object1", evaluator
+                .evaluate(attribute, request));
+    }
+
+    /**
+     * Tests {@link OGNLAttributeEvaluator#evaluate(String, Request)}.
+     */
+    @Test
+    public void testEvaluateString() {
+        String expression = "requestScope.object1";
+        assertEquals("The value is not correct", "value", evaluator.evaluate(
+                expression, request));
+        expression = "sessionScope.object2";
+        assertEquals("The value is not correct", new Integer(1), evaluator
+                .evaluate(expression, request));
+        expression = "applicationScope.object3";
+        assertEquals("The value is not correct", new Float(2.0), evaluator
+                .evaluate(expression, request));
+        expression = "object1";
+        assertEquals("The value is not correct", "value", evaluator.evaluate(
+                expression, request));
+        expression = "object2";
+        assertEquals("The value is not correct", new Integer(1), evaluator
+                .evaluate(expression, request));
+        expression = "object3";
+        assertEquals("The value is not correct", new Float(2.0), evaluator
+                .evaluate(expression, request));
+        expression = "paulaBean.paula";
+        assertEquals("The value is not correct", "Brillant", evaluator
+                .evaluate(expression, request));
+        expression = "'String literal'";
+        assertEquals("The value is not correct", "String literal", evaluator
+                .evaluate(expression, request));
+    }
+
+    /**
+     * Tests {@link OGNLAttributeEvaluator#evaluate(String, Request)}.
+     */
+    @Test(expected = IllegalArgumentException.class)
+    public void testEvaluateNull() {
+        evaluator.evaluate((String) null, request);
+    }
+
+    /**
+     * Tests {@link OGNLAttributeEvaluator#evaluate(String, Request)}.
+     */
+    @Test(expected = EvaluationException.class)
+    public void testEvaluateOgnlException() {
+        evaluator.evaluate("wrong|||!!!!yes###", request);
+    }
+
+    /**
+     * This is The Brillant Paula Bean (sic) just like it was posted to:
+     * http://thedailywtf.com/Articles/The_Brillant_Paula_Bean.aspx I hope that
+     * there is no copyright on it.
+     */
+    public static class PaulaBean {
+
+        /**
+         * Paula is brillant, really.
+         */
+        private String paula = "Brillant";
+
+        /**
+         * Returns brillant.
+         *
+         * @return "Brillant".
+         */
+        public String getPaula() {
+            return paula;
+        }
+    }
+}
diff --git a/Java-base/tiles/src/tiles-ognl/src/test/java/org/apache/tiles/ognl/ScopePropertyAccessorTest.java b/Java-base/tiles/src/tiles-ognl/src/test/java/org/apache/tiles/ognl/ScopePropertyAccessorTest.java
new file mode 100644
index 000000000..3bbc58c79
--- /dev/null
+++ b/Java-base/tiles/src/tiles-ognl/src/test/java/org/apache/tiles/ognl/ScopePropertyAccessorTest.java
@@ -0,0 +1,101 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.ognl;
+
+import static org.easymock.classextension.EasyMock.*;
+import static org.junit.Assert.*;
+
+import java.util.Map;
+
+import org.apache.tiles.request.Request;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests {@link ScopePropertyAccessor}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ScopePropertyAccessorTest {
+
+    /**
+     * The accessor to test.
+     */
+    private ScopePropertyAccessor accessor;
+
+    /**
+     * Sets up the test.
+     */
+    @Before
+    public void setUp() {
+        accessor = new ScopePropertyAccessor();
+    }
+
+    /**
+     * Test method for {@link ScopePropertyAccessor#getProperty(Map, Object, Object)}.
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testGetProperty() {
+        Request request = createMock(Request.class);
+        Map<String, Object> oneScope = createMock(Map.class);
+
+        expect(request.getContext("one")).andReturn(oneScope);
+
+        replay(request);
+        assertEquals(oneScope, accessor.getProperty(null, request, "oneScope"));
+        assertNull(accessor.getProperty(null, request, "whatever"));
+        verify(request);
+    }
+
+    /**
+     * Test method for {@link ScopePropertyAccessor#getSourceAccessor(OgnlContext, Object, Object)}.
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testGetSourceAccessor() {
+        Request request = createMock(Request.class);
+        @SuppressWarnings("unused")
+        Map<String, Object> oneScope = createMock(Map.class);
+
+        replay(request);
+        assertEquals(".getContext(\"one\")", accessor.getSourceAccessor(null, request, "oneScope"));
+        assertNull(accessor.getSourceAccessor(null, request, "whatever"));
+        verify(request);
+    }
+
+    /**
+     * Test method for {@link ScopePropertyAccessor#getSourceSetter(OgnlContext, Object, Object)}.
+     */
+    @Test
+    public void testGetSourceSetter() {
+        assertNull(accessor.getSourceSetter(null, null, "whatever"));
+    }
+
+    /**
+     * Test method for {@link ScopePropertyAccessor#setProperty(Map, Object, Object, Object)}.
+     */
+    @Test
+    public void testSetProperty() {
+        accessor.setProperty(null, null, "whatever", "whateverValue");
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-ognl/src/test/java/org/apache/tiles/ognl/TilesApplicationContextNestedObjectExtractorTest.java b/Java-base/tiles/src/tiles-ognl/src/test/java/org/apache/tiles/ognl/TilesApplicationContextNestedObjectExtractorTest.java
new file mode 100644
index 000000000..6fc1bb317
--- /dev/null
+++ b/Java-base/tiles/src/tiles-ognl/src/test/java/org/apache/tiles/ognl/TilesApplicationContextNestedObjectExtractorTest.java
@@ -0,0 +1,52 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.ognl;
+
+import static org.junit.Assert.*;
+import static org.easymock.EasyMock.*;
+
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.Request;
+import org.junit.Test;
+
+/**
+ * Tests {@link TilesApplicationContextNestedObjectExtractor}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TilesApplicationContextNestedObjectExtractorTest {
+
+    /**
+     * Tests {@link TilesApplicationContextNestedObjectExtractor#getNestedObject(Request)}.
+     */
+    @Test
+    public void testGetNestedObject() {
+        Request request = createMock(Request.class);
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        expect(request.getApplicationContext()).andReturn(applicationContext);
+
+        replay(request, applicationContext);
+        NestedObjectExtractor<Request> extractor = new TilesApplicationContextNestedObjectExtractor();
+        assertEquals(applicationContext, extractor.getNestedObject(request));
+        verify(request, applicationContext);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-ognl/src/test/java/org/apache/tiles/ognl/TilesContextPropertyAccessorDelegateFactoryTest.java b/Java-base/tiles/src/tiles-ognl/src/test/java/org/apache/tiles/ognl/TilesContextPropertyAccessorDelegateFactoryTest.java
new file mode 100644
index 000000000..66bfff08e
--- /dev/null
+++ b/Java-base/tiles/src/tiles-ognl/src/test/java/org/apache/tiles/ognl/TilesContextPropertyAccessorDelegateFactoryTest.java
@@ -0,0 +1,202 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.ognl;
+
+import static org.junit.Assert.*;
+import static org.easymock.EasyMock.*;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import ognl.PropertyAccessor;
+
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.Request;
+import org.junit.Test;
+
+/**
+ * Tests {@link TilesContextPropertyAccessorDelegateFactory}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TilesContextPropertyAccessorDelegateFactoryTest {
+
+    /**
+     * Test method for
+     * {@link TilesContextPropertyAccessorDelegateFactory#getPropertyAccessor(String, Request)}
+     * .
+     */
+    @Test
+    public void testGetPropertyAccessorRequest() {
+        PropertyAccessor objectPropertyAccessor = createMock(PropertyAccessor.class);
+        PropertyAccessor applicationContextPropertyAccessor = createMock(PropertyAccessor.class);
+        PropertyAccessor requestScopePropertyAccessor = createMock(PropertyAccessor.class);
+        PropertyAccessor sessionScopePropertyAccessor = createMock(PropertyAccessor.class);
+        PropertyAccessor applicationScopePropertyAccessor = createMock(PropertyAccessor.class);
+        Request request = createMock(Request.class);
+
+        replay(objectPropertyAccessor, applicationContextPropertyAccessor, requestScopePropertyAccessor,
+                sessionScopePropertyAccessor, applicationScopePropertyAccessor, request);
+        PropertyAccessorDelegateFactory<Request> factory = new TilesContextPropertyAccessorDelegateFactory(
+                objectPropertyAccessor, applicationContextPropertyAccessor,
+                requestScopePropertyAccessor, sessionScopePropertyAccessor);
+        assertEquals(objectPropertyAccessor, factory.getPropertyAccessor("writer", request));
+
+        verify(objectPropertyAccessor, applicationContextPropertyAccessor, requestScopePropertyAccessor,
+                sessionScopePropertyAccessor, applicationScopePropertyAccessor, request);
+    }
+
+    /**
+     * Test method for
+     * {@link TilesContextPropertyAccessorDelegateFactory#getPropertyAccessor(String, Request)}
+     * .
+     */
+    @Test
+    public void testGetPropertyAccessorApplication() {
+        PropertyAccessor objectPropertyAccessor = createMock(PropertyAccessor.class);
+        PropertyAccessor applicationContextPropertyAccessor = createMock(PropertyAccessor.class);
+        PropertyAccessor requestScopePropertyAccessor = createMock(PropertyAccessor.class);
+        PropertyAccessor sessionScopePropertyAccessor = createMock(PropertyAccessor.class);
+        PropertyAccessor applicationScopePropertyAccessor = createMock(PropertyAccessor.class);
+        Request request = createMock(Request.class);
+
+        replay(objectPropertyAccessor, applicationContextPropertyAccessor, requestScopePropertyAccessor,
+                sessionScopePropertyAccessor, applicationScopePropertyAccessor, request);
+        PropertyAccessorDelegateFactory<Request> factory = new TilesContextPropertyAccessorDelegateFactory(
+                objectPropertyAccessor, applicationContextPropertyAccessor,
+                requestScopePropertyAccessor, sessionScopePropertyAccessor);
+        assertEquals(applicationContextPropertyAccessor, factory.getPropertyAccessor("initParams", request));
+
+        verify(objectPropertyAccessor, applicationContextPropertyAccessor, requestScopePropertyAccessor,
+                sessionScopePropertyAccessor, applicationScopePropertyAccessor, request);
+    }
+
+    /**
+     * Test method for
+     * {@link TilesContextPropertyAccessorDelegateFactory#getPropertyAccessor(String, Request)}
+     * .
+     */
+    @Test
+    public void testGetPropertyAccessorRequestScope() {
+        PropertyAccessor objectPropertyAccessor = createMock(PropertyAccessor.class);
+        PropertyAccessor applicationContextPropertyAccessor = createMock(PropertyAccessor.class);
+        PropertyAccessor requestScopePropertyAccessor = createMock(PropertyAccessor.class);
+        PropertyAccessor sessionScopePropertyAccessor = createMock(PropertyAccessor.class);
+        PropertyAccessor applicationScopePropertyAccessor = createMock(PropertyAccessor.class);
+        Request request = createMock(Request.class);
+        Map<String, Object> map = new HashMap<String, Object>();
+        map.put("attribute", 1);
+
+        replay(objectPropertyAccessor, applicationContextPropertyAccessor, requestScopePropertyAccessor,
+                sessionScopePropertyAccessor, applicationScopePropertyAccessor, request);
+        PropertyAccessorDelegateFactory<Request> factory = new TilesContextPropertyAccessorDelegateFactory(
+                objectPropertyAccessor, applicationContextPropertyAccessor,
+                requestScopePropertyAccessor, sessionScopePropertyAccessor);
+        assertEquals(requestScopePropertyAccessor, factory.getPropertyAccessor("attribute", request));
+
+        verify(objectPropertyAccessor, applicationContextPropertyAccessor, requestScopePropertyAccessor,
+                sessionScopePropertyAccessor, applicationScopePropertyAccessor, request);
+    }
+
+    /**
+     * Test method for
+     * {@link TilesContextPropertyAccessorDelegateFactory#getPropertyAccessor(String, Request)}
+     * .
+     */
+    @Test
+    public void testGetPropertyAccessorSessionScope() {
+        PropertyAccessor objectPropertyAccessor = createMock(PropertyAccessor.class);
+        PropertyAccessor applicationContextPropertyAccessor = createMock(PropertyAccessor.class);
+        PropertyAccessor requestScopePropertyAccessor = createMock(PropertyAccessor.class);
+        PropertyAccessor sessionScopePropertyAccessor = createMock(PropertyAccessor.class);
+        PropertyAccessor applicationScopePropertyAccessor = createMock(PropertyAccessor.class);
+        Request request = createMock(Request.class);
+        Map<String, Object> map = new HashMap<String, Object>();
+        map.put("attribute", 1);
+
+        replay(objectPropertyAccessor, applicationContextPropertyAccessor, requestScopePropertyAccessor,
+                sessionScopePropertyAccessor, applicationScopePropertyAccessor, request);
+        PropertyAccessorDelegateFactory<Request> factory = new TilesContextPropertyAccessorDelegateFactory(
+                objectPropertyAccessor, applicationContextPropertyAccessor,
+                requestScopePropertyAccessor, sessionScopePropertyAccessor);
+        assertEquals(requestScopePropertyAccessor, factory.getPropertyAccessor("attribute", request));
+
+        verify(objectPropertyAccessor, applicationContextPropertyAccessor, requestScopePropertyAccessor,
+                sessionScopePropertyAccessor, applicationScopePropertyAccessor, request);
+    }
+
+    /**
+     * Test method for
+     * {@link TilesContextPropertyAccessorDelegateFactory#getPropertyAccessor(String, Request)}
+     * .
+     */
+    @Test
+    public void testGetPropertyAccessorApplicationScope() {
+        PropertyAccessor objectPropertyAccessor = createMock(PropertyAccessor.class);
+        PropertyAccessor applicationContextPropertyAccessor = createMock(PropertyAccessor.class);
+        PropertyAccessor requestScopePropertyAccessor = createMock(PropertyAccessor.class);
+        PropertyAccessor sessionScopePropertyAccessor = createMock(PropertyAccessor.class);
+        PropertyAccessor applicationScopePropertyAccessor = createMock(PropertyAccessor.class);
+        Request request = createMock(Request.class);
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        Map<String, Object> map = new HashMap<String, Object>();
+        map.put("attribute", 1);
+
+        replay(objectPropertyAccessor, applicationContextPropertyAccessor, requestScopePropertyAccessor,
+                sessionScopePropertyAccessor, applicationScopePropertyAccessor, request, applicationContext);
+        PropertyAccessorDelegateFactory<Request> factory = new TilesContextPropertyAccessorDelegateFactory(
+                objectPropertyAccessor, applicationContextPropertyAccessor,
+                requestScopePropertyAccessor, sessionScopePropertyAccessor);
+        assertEquals(requestScopePropertyAccessor, factory.getPropertyAccessor("attribute", request));
+
+        verify(objectPropertyAccessor, applicationContextPropertyAccessor, requestScopePropertyAccessor,
+                sessionScopePropertyAccessor, applicationScopePropertyAccessor, request, applicationContext);
+    }
+
+    /**
+     * Test method for
+     * {@link TilesContextPropertyAccessorDelegateFactory#getPropertyAccessor(String, Request)}
+     * .
+     */
+    @Test
+    public void testGetPropertyAccessorRequestScopeDefault() {
+        PropertyAccessor objectPropertyAccessor = createMock(PropertyAccessor.class);
+        PropertyAccessor applicationContextPropertyAccessor = createMock(PropertyAccessor.class);
+        PropertyAccessor requestScopePropertyAccessor = createMock(PropertyAccessor.class);
+        PropertyAccessor sessionScopePropertyAccessor = createMock(PropertyAccessor.class);
+        PropertyAccessor applicationScopePropertyAccessor = createMock(PropertyAccessor.class);
+        Request request = createMock(Request.class);
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        Map<String, Object> map = new HashMap<String, Object>();
+        map.put("anotherAttribute", 1);
+
+        replay(objectPropertyAccessor, applicationContextPropertyAccessor, requestScopePropertyAccessor,
+                sessionScopePropertyAccessor, applicationScopePropertyAccessor, request, applicationContext);
+        PropertyAccessorDelegateFactory<Request> factory = new TilesContextPropertyAccessorDelegateFactory(
+                objectPropertyAccessor, applicationContextPropertyAccessor,
+                requestScopePropertyAccessor, sessionScopePropertyAccessor);
+        assertEquals(requestScopePropertyAccessor, factory.getPropertyAccessor("attribute", request));
+
+        verify(objectPropertyAccessor, applicationContextPropertyAccessor, requestScopePropertyAccessor,
+                sessionScopePropertyAccessor, applicationScopePropertyAccessor, request, applicationContext);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-servlet/pom.xml b/Java-base/tiles/src/tiles-servlet/pom.xml
new file mode 100644
index 000000000..1e2881ebc
--- /dev/null
+++ b/Java-base/tiles/src/tiles-servlet/pom.xml
@@ -0,0 +1,141 @@
+<?xml version="1.0"?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+  <parent>
+    <groupId>org.apache.tiles</groupId>
+    <artifactId>tiles-parent</artifactId>
+    <version>3.1-SNAPSHOT</version>
+  </parent>
+
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>tiles-servlet</artifactId>
+  <packaging>jar</packaging>
+  <name>Tiles - Servlet support</name>
+  <description>Tiles servlet support, to enable use of Tiles inside a Servlet environment.
+  </description>
+
+  <properties>
+      <tiles.osgi.symbolicName>org.apache.tiles.servlet</tiles.osgi.symbolicName>
+  </properties>
+
+  <build>
+    <resources>
+      <resource>
+        <directory>src/main/resources</directory>
+        <excludes>
+          <exclude>LICENSE.txt</exclude>
+          <exclude>NOTICE.txt</exclude>
+        </excludes>
+      </resource>
+      <resource>
+        <directory>src/main/resources</directory>
+        <includes>
+          <include>LICENSE.txt</include>
+          <include>NOTICE.txt</include>
+        </includes>
+        <targetPath>META-INF</targetPath>
+      </resource>
+    </resources>
+
+    <plugins>
+      <plugin>
+        <artifactId>maven-jar-plugin</artifactId>
+        <configuration>
+          <archive>
+            <manifest>
+            </manifest>
+          </archive>
+        </configuration>
+      </plugin>
+    </plugins>
+
+  </build>
+
+  <reporting>
+    <plugins>
+      <plugin>
+        <groupId>net.sf.dtddoc</groupId>
+        <artifactId>dtddoc-maven-plugin</artifactId>
+        <version>1.1</version>
+        <configuration>
+          <docTitle>Tiles Definition File</docTitle>
+        </configuration>
+      </plugin>
+    </plugins>
+  </reporting>
+
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.tiles</groupId>
+      <artifactId>tiles-core</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>jcl-over-slf4j</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-jdk14</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>javax.servlet</groupId>
+      <artifactId>servlet-api</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.easymock</groupId>
+      <artifactId>easymockclassextension</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.shale</groupId>
+      <artifactId>shale-test</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+        <groupId>org.apache.tiles</groupId>
+        <artifactId>tiles-request-servlet</artifactId>
+        <version>${tiles.request.version}</version>
+    </dependency>
+  </dependencies>
+
+</project>
diff --git a/Java-base/tiles/src/tiles-servlet/src/main/java/org/apache/tiles/web/startup/AbstractTilesInitializerServlet.java b/Java-base/tiles/src/tiles-servlet/src/main/java/org/apache/tiles/web/startup/AbstractTilesInitializerServlet.java
new file mode 100644
index 000000000..b4d2558cf
--- /dev/null
+++ b/Java-base/tiles/src/tiles-servlet/src/main/java/org/apache/tiles/web/startup/AbstractTilesInitializerServlet.java
@@ -0,0 +1,73 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.web.startup;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServlet;
+
+import org.apache.tiles.request.servlet.ServletApplicationContext;
+import org.apache.tiles.startup.TilesInitializer;
+import org.apache.tiles.web.util.ServletContextAdapter;
+
+/**
+ * Abstract Initialization Servlet. Uses a {@link TilesInitializer}, created by
+ * {@link #createTilesInitializer()} to initialize Tiles.
+ *
+ * @deprecated use {@link AbstractTilesListener} instead.
+ * @see org.apache.tiles.web.startup.TilesListener
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+@Deprecated
+public abstract class AbstractTilesInitializerServlet extends HttpServlet {
+
+    /**
+     * The private listener instance, that is used to initialize Tiles
+     * container.
+     */
+    private TilesInitializer initializer;
+
+    /** {@inheritDoc} */
+    @Override
+    public void destroy() {
+        initializer.destroy();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public void init() {
+        initializer = createTilesInitializer();
+        ServletContext adaptedContext = new ServletContextAdapter(
+                getServletConfig());
+        ServletApplicationContext preliminaryContext = new ServletApplicationContext(
+                adaptedContext);
+        initializer.initialize(preliminaryContext);
+    }
+
+    /**
+     * Creates a new instance of {@link TilesInitializer}. Implement it to use
+     * your custom initializer.
+     *
+     * @return The Tiles servlet-based initializer.
+     * @since 2.2.0
+     */
+    protected abstract TilesInitializer createTilesInitializer();
+}
diff --git a/Java-base/tiles/src/tiles-servlet/src/main/java/org/apache/tiles/web/startup/AbstractTilesListener.java b/Java-base/tiles/src/tiles-servlet/src/main/java/org/apache/tiles/web/startup/AbstractTilesListener.java
new file mode 100644
index 000000000..40a8b2440
--- /dev/null
+++ b/Java-base/tiles/src/tiles-servlet/src/main/java/org/apache/tiles/web/startup/AbstractTilesListener.java
@@ -0,0 +1,74 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.web.startup;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+
+import org.apache.tiles.request.servlet.ServletApplicationContext;
+import org.apache.tiles.startup.TilesInitializer;
+
+/**
+ * Listener for the initialization of the Tiles container.
+ *
+ * @version $Rev$ $Date$
+ */
+public abstract class AbstractTilesListener implements ServletContextListener {
+
+    /**
+     * The initializer object.
+     *
+     * @since 2.1.2
+     */
+    protected TilesInitializer initializer;
+
+    /**
+     * Initialize the TilesContainer and place it
+     * into service.
+     *
+     * @param event The intercepted event.
+     */
+    public void contextInitialized(ServletContextEvent event) {
+        ServletContext servletContext = event.getServletContext();
+        initializer = createTilesInitializer();
+        initializer.initialize(new ServletApplicationContext(
+                servletContext));
+    }
+
+    /**
+     * Destroys the initializer.
+     *
+     * @param event The intercepted event.
+     */
+    public void contextDestroyed(ServletContextEvent event) {
+        initializer.destroy();
+    }
+
+    /**
+     * Creates a new instance of {@link TilesInitializer}. Implement it to use a
+     * different initializer.
+     *
+     * @return The Tiles servlet-based initializer.
+     * @since 2.2.0
+     */
+    protected abstract TilesInitializer createTilesInitializer();
+}
diff --git a/Java-base/tiles/src/tiles-servlet/src/main/java/org/apache/tiles/web/startup/package-info.java b/Java-base/tiles/src/tiles-servlet/src/main/java/org/apache/tiles/web/startup/package-info.java
new file mode 100644
index 000000000..6dc2fd3d2
--- /dev/null
+++ b/Java-base/tiles/src/tiles-servlet/src/main/java/org/apache/tiles/web/startup/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * $Id: package-info.java 1049711 2010-12-15 21:12:00Z apetrelli $
+ *
+ * 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.
+ */
+/**
+ * Classes to start the Tiles engine up in a web environment.
+ */
+package org.apache.tiles.web.startup;
diff --git a/Java-base/tiles/src/tiles-servlet/src/main/java/org/apache/tiles/web/startup/simple/SimpleTilesInitializerServlet.java b/Java-base/tiles/src/tiles-servlet/src/main/java/org/apache/tiles/web/startup/simple/SimpleTilesInitializerServlet.java
new file mode 100644
index 000000000..0159db302
--- /dev/null
+++ b/Java-base/tiles/src/tiles-servlet/src/main/java/org/apache/tiles/web/startup/simple/SimpleTilesInitializerServlet.java
@@ -0,0 +1,43 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.web.startup.simple;
+
+import org.apache.tiles.startup.DefaultTilesInitializer;
+import org.apache.tiles.startup.TilesInitializer;
+import org.apache.tiles.web.startup.AbstractTilesInitializerServlet;
+
+/**
+ * A Tiles listener that loads Tiles in the default way.
+ *
+ * @deprecated use {@link SimpleTilesListener} instead.
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+@Deprecated
+public class SimpleTilesInitializerServlet extends AbstractTilesInitializerServlet {
+
+    /** {@inheritDoc} */
+    @Override
+    protected TilesInitializer createTilesInitializer() {
+        return new DefaultTilesInitializer();
+    }
+}
diff --git a/Java-base/tiles/src/tiles-servlet/src/main/java/org/apache/tiles/web/startup/simple/SimpleTilesListener.java b/Java-base/tiles/src/tiles-servlet/src/main/java/org/apache/tiles/web/startup/simple/SimpleTilesListener.java
new file mode 100644
index 000000000..6474b8e27
--- /dev/null
+++ b/Java-base/tiles/src/tiles-servlet/src/main/java/org/apache/tiles/web/startup/simple/SimpleTilesListener.java
@@ -0,0 +1,41 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.web.startup.simple;
+
+import org.apache.tiles.startup.DefaultTilesInitializer;
+import org.apache.tiles.startup.TilesInitializer;
+import org.apache.tiles.web.startup.AbstractTilesListener;
+
+/**
+ * A Tiles listener that loads Tiles in the default way.
+ *
+ * @version $Rev$ $Date$ù
+ * @since 2.2.0
+ */
+public class SimpleTilesListener extends AbstractTilesListener {
+
+    /** {@inheritDoc} */
+    @Override
+    protected TilesInitializer createTilesInitializer() {
+        return new DefaultTilesInitializer();
+    }
+}
diff --git a/Java-base/tiles/src/tiles-servlet/src/main/java/org/apache/tiles/web/startup/simple/package-info.java b/Java-base/tiles/src/tiles-servlet/src/main/java/org/apache/tiles/web/startup/simple/package-info.java
new file mode 100644
index 000000000..68f96c2d5
--- /dev/null
+++ b/Java-base/tiles/src/tiles-servlet/src/main/java/org/apache/tiles/web/startup/simple/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * $Id: package-info.java 1049711 2010-12-15 21:12:00Z apetrelli $
+ *
+ * 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.
+ */
+/**
+ * Classes to start the Tiles engine up in a web environment using the default settings.
+ */
+package org.apache.tiles.web.startup.simple;
diff --git a/Java-base/tiles/src/tiles-servlet/src/main/java/org/apache/tiles/web/util/AttributeContextMutator.java b/Java-base/tiles/src/tiles-servlet/src/main/java/org/apache/tiles/web/util/AttributeContextMutator.java
new file mode 100644
index 000000000..2e96a7163
--- /dev/null
+++ b/Java-base/tiles/src/tiles-servlet/src/main/java/org/apache/tiles/web/util/AttributeContextMutator.java
@@ -0,0 +1,45 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.web.util;
+
+import org.apache.tiles.AttributeContext;
+
+import javax.servlet.ServletRequest;
+
+/**
+ * It represents an object able to manipulate a <code>AttributeContext</code>.
+ * In other words, it is able to add, replace and remove attributes from the
+ * <code>AttributeContext</code>.
+ *
+ * @since Tiles 2.0
+ * @version $Rev$ $Date$
+ */
+public interface AttributeContextMutator {
+
+    /**
+     * Mutate a <code>AttributeContext</code>.
+     *
+     * @param context The attribute context to mutate.
+     * @param request The current servlet request.
+     */
+    void mutate(AttributeContext context, ServletRequest request);
+
+}
diff --git a/Java-base/tiles/src/tiles-servlet/src/main/java/org/apache/tiles/web/util/ServletContextAdapter.java b/Java-base/tiles/src/tiles-servlet/src/main/java/org/apache/tiles/web/util/ServletContextAdapter.java
new file mode 100644
index 000000000..4d8fe916a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-servlet/src/main/java/org/apache/tiles/web/util/ServletContextAdapter.java
@@ -0,0 +1,209 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.web.util;
+
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Set;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.Servlet;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+
+/**
+ * Adapts a servlet config and a servlet context to become a unique servlet
+ * context.
+ *
+ * @version $Rev$ $Date$
+ */
+@SuppressWarnings("deprecation")
+public class ServletContextAdapter implements ServletContext {
+
+    /**
+     * The root context to use.
+     */
+    private ServletContext rootContext;
+
+    /**
+     * The union of init parameters of {@link ServletConfig} and
+     * {@link ServletContext}.
+     */
+    private Hashtable<String, String> initParameters;
+
+
+    /**
+     * Constructor.
+     *
+     * @param config The servlet configuration object.
+     */
+    @SuppressWarnings("unchecked")
+    public ServletContextAdapter(ServletConfig config) {
+        this.rootContext = config.getServletContext();
+        initParameters = new Hashtable<String, String>();
+        Enumeration<String> enumeration = rootContext
+                .getInitParameterNames();
+        while (enumeration.hasMoreElements()) {
+            String paramName = enumeration.nextElement();
+            initParameters.put(paramName, rootContext
+                    .getInitParameter(paramName));
+        }
+        enumeration = config.getInitParameterNames();
+        while (enumeration.hasMoreElements()) {
+            String paramName = enumeration.nextElement();
+            initParameters.put(paramName, config.getInitParameter(paramName));
+        }
+    }
+
+    /** {@inheritDoc} */
+    public ServletContext getContext(String string) {
+        return rootContext.getContext(string);
+    }
+
+    /** {@inheritDoc} */
+    public int getMajorVersion() {
+        return rootContext.getMajorVersion();
+    }
+
+    /** {@inheritDoc} */
+    public int getMinorVersion() {
+        return rootContext.getMinorVersion();
+    }
+
+    /** {@inheritDoc} */
+    public String getMimeType(String string) {
+        return rootContext.getMimeType(string);
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings({ "rawtypes" })
+    public Set getResourcePaths(String string) {
+        return rootContext.getResourcePaths(string);
+    }
+
+    /** {@inheritDoc} */
+    public URL getResource(String string) throws MalformedURLException {
+        return rootContext.getResource(string);
+    }
+
+    /** {@inheritDoc} */
+    public InputStream getResourceAsStream(String string) {
+        return rootContext.getResourceAsStream(string);
+    }
+
+    /** {@inheritDoc} */
+    public RequestDispatcher getRequestDispatcher(String string) {
+        return rootContext.getRequestDispatcher(string);
+    }
+
+    /** {@inheritDoc} */
+    public RequestDispatcher getNamedDispatcher(String string) {
+        return rootContext.getNamedDispatcher(string);
+    }
+
+    /** {@inheritDoc} */
+    public Servlet getServlet(String string) throws ServletException {
+        return rootContext.getServlet(string);
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("rawtypes")
+    public Enumeration getServlets() {
+        return rootContext.getServlets();  //To change body of implemented methods use File | Settings | File Templates.
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("rawtypes")
+    public Enumeration getServletNames() {
+        return rootContext.getServletNames();
+    }
+
+    /** {@inheritDoc} */
+    public void log(String string) {
+        rootContext.log(string);
+    }
+
+    /** {@inheritDoc} */
+    public void log(Exception exception, String string) {
+        rootContext.log(exception, string);
+    }
+
+    /** {@inheritDoc} */
+    public void log(String string, Throwable throwable) {
+        rootContext.log(string, throwable);
+    }
+
+    /** {@inheritDoc} */
+    public String getRealPath(String string) {
+        return rootContext.getRealPath(string);
+    }
+
+    /** {@inheritDoc} */
+    public String getServerInfo() {
+        return rootContext.getServerInfo();
+    }
+
+    /** {@inheritDoc} */
+    public String getInitParameter(String string) {
+        return initParameters.get(string);
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("rawtypes")
+    public Enumeration getInitParameterNames() {
+        return initParameters.keys();
+    }
+
+    /** {@inheritDoc} */
+    public Object getAttribute(String string) {
+        return rootContext.getAttribute(string);
+    }
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("rawtypes")
+    public Enumeration getAttributeNames() {
+        return rootContext.getAttributeNames();
+    }
+
+    /** {@inheritDoc} */
+    public void setAttribute(String string, Object object) {
+        rootContext.setAttribute(string, object);
+    }
+
+    /** {@inheritDoc} */
+    public void removeAttribute(String string) {
+        rootContext.removeAttribute(string);
+    }
+
+    /** {@inheritDoc} */
+    public String getServletContextName() {
+        return rootContext.getServletContextName();
+    }
+
+    /** {@inheritDoc} */
+    public String getContextPath() {
+        return rootContext.getContextPath();
+    }
+}
diff --git a/Java-base/tiles/src/tiles-servlet/src/main/java/org/apache/tiles/web/util/TilesDecorationFilter.java b/Java-base/tiles/src/tiles-servlet/src/main/java/org/apache/tiles/web/util/TilesDecorationFilter.java
new file mode 100644
index 000000000..35cbbfb66
--- /dev/null
+++ b/Java-base/tiles/src/tiles-servlet/src/main/java/org/apache/tiles/web/util/TilesDecorationFilter.java
@@ -0,0 +1,296 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.web.util;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.AttributeContext;
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.access.TilesAccess;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.Request;
+import org.apache.tiles.request.reflect.CannotInstantiateObjectException;
+import org.apache.tiles.request.reflect.ClassUtil;
+import org.apache.tiles.request.servlet.ServletRequest;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Decoration Filter.  Intercepts all requests and decorates them
+ * with the configured definition.
+ * <p/>
+ * For example, given the following config:
+ * &lt;xmp&gt;
+ * &lt;filter&gt;
+ * &lt;filter-name&gt;Tiles Decoration Filter&lt;/filter-name&gt;
+ * &lt;filter-class&gt;org.apache.tiles.web.TilesDecorationFilter&lt;/filter-class&gt;
+ * &lt;init-param&gt;
+ * &lt;param-name&gt;definition&lt;/param-name&gt;
+ * &lt;param-value&gt;test.definition&lt;/param-value&gt;
+ * &lt;/init-param&gt;
+ * &lt;init-param&gt;
+ * &lt;param-name&gt;attribute-name&lt;/param-name&gt;
+ * &lt;param-value&gt;body&lt;/param-value&gt;
+ * &lt;/init-param&gt;
+ * &lt;init-param&gt;
+ * &lt;param-name&gt;prevent-token&lt;/param-name&gt;
+ * &lt;param-value&gt;layout&lt;/param-value&gt;
+ * &lt;/init-param&gt;
+ * &lt;/filter&gt;
+ * <p/>
+ * &lt;filter-mapping&gt;
+ * &lt;filter-name&gt;Tiles Decoration Filter&lt;/filter-name&gt;
+ * &lt;url-pattern&gt;/testdecorationfilter.jsp&lt;/url-pattern&gt;
+ * &lt;dispatcher&gt;REQUEST&lt;/dispatcher&gt;
+ * &lt;/filter-mapping&gt;
+ * &lt;/xmp&gt;
+ * The filter will intercept all requests to the indicated url pattern
+ * store the initial request path as the "body"  attribute and then render the
+ * "test.definition" definition.  The filter will only redecorate those requests
+ * which do not contain the request attribute associated with the prevent token
+ * "layout".
+ */
+public class TilesDecorationFilter implements Filter {
+
+    /**
+     * Init parameter to define the key of the container to use.
+     *
+     * @since 2.1.2
+     */
+    public static final String CONTAINER_KEY_INIT_PARAMETER =
+        "org.apache.tiles.web.util.TilesDecorationFilter.CONTAINER_KEY";
+
+    /**
+     * The logging object.
+     */
+    private Logger log = LoggerFactory.getLogger(TilesDecorationFilter.class);
+
+    /**
+     * Filter configuration.
+     */
+    private FilterConfig filterConfig;
+
+    /**
+     * The key under which the container is stored.
+     */
+    private String containerKey;
+
+    /**
+     * The name of the definition attribute used to
+     * pass on the request.
+     */
+    private String definitionAttributeName = "content";
+
+    /**
+     * The definition name to use.
+     */
+    private String definitionName = "layout";
+
+    /**
+     * Token used to prevent re-decoration of requests.
+     * This token is used to prevent infinate loops on
+     * filters configured to match wildcards.
+     */
+    private String preventDecorationToken;
+
+    /**
+     * Stores a map of the type "mask -> definition": when a definition name
+     * mask is identified, it is substituted with the configured definition.
+     */
+    private Map<String, String> alternateDefinitions;
+
+    /**
+     * The object that will mutate the attribute context so that it uses
+     * different attributes.
+     */
+    private AttributeContextMutator mutator = null;
+
+    /**
+     * The servlet context.
+     */
+    private ServletContext servletContext;
+
+    /** {@inheritDoc} */
+    public void init(FilterConfig config) throws ServletException {
+        filterConfig = config;
+        servletContext = filterConfig.getServletContext();
+
+        containerKey = filterConfig
+                .getInitParameter(CONTAINER_KEY_INIT_PARAMETER);
+
+        String temp = config.getInitParameter("attribute-name");
+        if (temp != null) {
+            definitionAttributeName = temp;
+        }
+
+        temp = config.getInitParameter("definition");
+        if (temp != null) {
+            definitionName = temp;
+        }
+
+        temp = config.getInitParameter("prevent-token");
+        preventDecorationToken = "org.apache.tiles.decoration.PREVENT:"
+                + (temp == null ? definitionName : temp);
+
+        alternateDefinitions = parseAlternateDefinitions();
+
+        temp = config.getInitParameter("mutator");
+        if (temp != null) {
+            try {
+                mutator = (AttributeContextMutator) ClassUtil.instantiate(temp);
+            } catch (CannotInstantiateObjectException e) {
+                throw new ServletException("Unable to instantiate specified context mutator.", e);
+            }
+        } else {
+            mutator = new DefaultMutator();
+        }
+    }
+
+    /**
+     * Creates the alternate definitions map, to map a mask of definition names
+     * to a configured definition.
+     *
+     * @return The alternate definitions map.
+     */
+    @SuppressWarnings("unchecked")
+    protected Map<String, String> parseAlternateDefinitions() {
+        Map<String, String> map = new HashMap<String, String>();
+        Enumeration<String> e = filterConfig.getInitParameterNames();
+        while (e.hasMoreElements()) {
+            String parm = e.nextElement();
+            if (parm.startsWith("definition(") && parm.endsWith("*)")) {
+                String value = filterConfig.getInitParameter(parm);
+                String mask = parm.substring("definition(".length());
+                mask = mask.substring(0, mask.lastIndexOf("*)"));
+                map.put(mask, value);
+                log.info("Mapping all requests matching '" + mask
+                        + "*' to definition '" + value + "'");
+            }
+        }
+        return map;
+    }
+
+    /** {@inheritDoc} */
+    public void destroy() {
+        filterConfig = null;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     */
+    public void doFilter(javax.servlet.ServletRequest req, ServletResponse res, FilterChain filterChain)
+            throws IOException, ServletException {
+        // If the request contains the prevent token, we must not reapply the definition.
+        // This is used to ensure that filters mapped to wild cards do not infinately
+        // loop.
+        if (!isPreventTokenPresent(req)) {
+            ApplicationContext applicationContext = org.apache.tiles.request.servlet.ServletUtil
+                    .getApplicationContext(servletContext);
+            Request request = new ServletRequest(applicationContext,
+                    (HttpServletRequest) req, (HttpServletResponse) res);
+            TilesContainer container = TilesAccess.getContainer(applicationContext,
+                    containerKey);
+            mutator.mutate(container.getAttributeContext(request), req);
+            if (preventDecorationToken != null) {
+                req.setAttribute(preventDecorationToken, Boolean.TRUE);
+            }
+            String definitionName = getDefinitionForRequest(req);
+            container.render(definitionName, request);
+        }
+        filterChain.doFilter(req, res);
+    }
+
+    /**
+     * Returns the final definition to render for the given request.
+     *
+     * @param request The request object.
+     * @return The final definition name.
+     */
+    private String getDefinitionForRequest(javax.servlet.ServletRequest request) {
+        if (alternateDefinitions.size() < 1) {
+            return definitionName;
+        }
+        String base = getRequestBase(request);
+        for (Map.Entry<String, String> pair : alternateDefinitions.entrySet()) {
+            if (base.startsWith(pair.getKey())) {
+                return pair.getValue();
+            }
+        }
+        return definitionName;
+    }
+
+    /**
+     * Returns the request base, i.e. the the URL to calculate all the relative
+     * paths.
+     *
+     * @param request The request object to use.
+     * @return The request base.
+     */
+    private String getRequestBase(javax.servlet.ServletRequest request) {
+        // Included Path
+        String include = (String) request.getAttribute("javax.servlet.include.servlet_path");
+        if (include != null) {
+            return include;
+        }
+
+        // As opposed to includes, if a forward occurs, it will update the servletPath property
+        // and include the original as the request attribute.
+        return ((HttpServletRequest) request).getServletPath();
+    }
+
+    /**
+     * The default attribute context mutator to use.
+     */
+    class DefaultMutator implements AttributeContextMutator {
+
+        /** {@inheritDoc} */
+        public void mutate(AttributeContext ctx, javax.servlet.ServletRequest req) {
+            Attribute attr = new Attribute();
+            attr.setRenderer("template");
+            attr.setValue(getRequestBase(req));
+            ctx.putAttribute(definitionAttributeName, attr);
+        }
+    }
+
+    /**
+     * Checks if the prevent evaluation token is present.
+     *
+     * @param request The HTTP request object.
+     * @return <code>true</code> if the token is present.
+     */
+    private boolean isPreventTokenPresent(javax.servlet.ServletRequest request) {
+        return preventDecorationToken != null && request.getAttribute(preventDecorationToken) != null;
+    }
+}
diff --git a/Java-base/tiles/src/tiles-servlet/src/main/java/org/apache/tiles/web/util/TilesDispatchServlet.java b/Java-base/tiles/src/tiles-servlet/src/main/java/org/apache/tiles/web/util/TilesDispatchServlet.java
new file mode 100644
index 000000000..0e63551ad
--- /dev/null
+++ b/Java-base/tiles/src/tiles-servlet/src/main/java/org/apache/tiles/web/util/TilesDispatchServlet.java
@@ -0,0 +1,143 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.web.util;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.tiles.AttributeContext;
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.access.TilesAccess;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.Request;
+import org.apache.tiles.request.reflect.ClassUtil;
+import org.apache.tiles.request.servlet.ServletRequest;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Tiles dispatching servlet.  Used to invoke
+ * a definition directly.
+ */
+public class TilesDispatchServlet extends HttpServlet {
+
+    /**
+     * Init parameter to define the key of the container to use.
+     *
+     * @since 2.1.2
+     */
+    public static final String CONTAINER_KEY_INIT_PARAMETER =
+        "org.apache.tiles.web.util.TilesDispatchServlet.CONTAINER_KEY";
+
+    /**
+     * The logging object.
+     */
+    private final Logger log = LoggerFactory
+            .getLogger(TilesDispatchServlet.class);
+
+    /**
+     * The key under which the container is stored.
+     */
+    private String containerKey;
+
+    /**
+     * The object that will mutate the attribute context so that it uses
+     * different attributes.
+     */
+    private AttributeContextMutator mutator;
+
+
+    /** {@inheritDoc} */
+    @Override
+    public void init() throws ServletException {
+        super.init();
+
+        containerKey = getServletConfig().getInitParameter(
+                CONTAINER_KEY_INIT_PARAMETER);
+
+        String temp = getInitParameter("mutator");
+        if (temp != null) {
+            try {
+                mutator = (AttributeContextMutator) ClassUtil.instantiate(temp);
+            } catch (Exception e) {
+                throw new ServletException("Unable to instantiate specified context mutator.", e);
+            }
+        } else {
+            mutator = new DefaultMutator();
+        }
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected void doGet(HttpServletRequest req, HttpServletResponse res) {
+
+        ApplicationContext applicationContext = org.apache.tiles.request.servlet.ServletUtil
+                .getApplicationContext(getServletContext());
+        Request request = new ServletRequest(applicationContext,
+                req, res);
+        TilesContainer container = TilesAccess.getContainer(applicationContext,
+                containerKey);
+        mutator.mutate(container.getAttributeContext(request), req);
+        String definition = getDefinitionName(req);
+        if (log.isDebugEnabled()) {
+            log.info("Dispatching to tile '" + definition + "'");
+        }
+        container.render(definition, request);
+    }
+
+    /**
+     * Returns the called definition name for the given request.
+     *
+     * @param request The request to parse.
+     * @return The definition name to render.
+     */
+    protected String getDefinitionName(HttpServletRequest request) {
+        String path = (String) request.getAttribute("javax.servlet.include.servlet_path");
+        if (path == null) {
+            path = request.getServletPath();
+        }
+
+        int start = path.startsWith("/") ? 1 : 0;
+        int end = path.endsWith(".tiles") ? path.indexOf(".tiles") : path.length();
+
+        return path.substring(start, end);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected void doPost(HttpServletRequest req, HttpServletResponse res) {
+        log.info("Tiles dispatch request received. Redirecting POST to GET.");
+        doGet(req, res);
+    }
+
+    /**
+     * Default no-op mutator.
+     */
+    class DefaultMutator implements AttributeContextMutator {
+
+        /** {@inheritDoc} */
+        public void mutate(AttributeContext context, javax.servlet.ServletRequest request) {
+            // noop;
+        }
+    }
+}
diff --git a/Java-base/tiles/src/tiles-servlet/src/main/java/org/apache/tiles/web/util/package-info.java b/Java-base/tiles/src/tiles-servlet/src/main/java/org/apache/tiles/web/util/package-info.java
new file mode 100644
index 000000000..4a373d94f
--- /dev/null
+++ b/Java-base/tiles/src/tiles-servlet/src/main/java/org/apache/tiles/web/util/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * $Id: package-info.java 1049711 2010-12-15 21:12:00Z apetrelli $
+ *
+ * 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.
+ */
+/**
+ * Utility classes to use Tiles in a servlet environment.
+ */
+package org.apache.tiles.web.util;
diff --git a/Java-base/tiles/src/tiles-servlet/src/main/resources/LICENSE.txt b/Java-base/tiles/src/tiles-servlet/src/main/resources/LICENSE.txt
new file mode 100644
index 000000000..d64569567
--- /dev/null
+++ b/Java-base/tiles/src/tiles-servlet/src/main/resources/LICENSE.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/Java-base/tiles/src/tiles-servlet/src/main/resources/NOTICE.txt b/Java-base/tiles/src/tiles-servlet/src/main/resources/NOTICE.txt
new file mode 100644
index 000000000..1f13ff856
--- /dev/null
+++ b/Java-base/tiles/src/tiles-servlet/src/main/resources/NOTICE.txt
@@ -0,0 +1,6 @@
+   Apache Tiles
+   Copyright 1999-2009 The Apache Software Foundation
+
+   This product includes software developed at
+   The Apache Software Foundation (http://www.apache.org/).
+
diff --git a/Java-base/tiles/src/tiles-servlet/src/site/site.xml b/Java-base/tiles/src/tiles-servlet/src/site/site.xml
new file mode 100644
index 000000000..43730c51c
--- /dev/null
+++ b/Java-base/tiles/src/tiles-servlet/src/site/site.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<project name="Apache Tiles - Servlet Support">
+     <skin>
+        <groupId>org.apache.maven.skins</groupId>
+        <artifactId>maven-fluido-skin</artifactId>
+        <version>1.3.0</version>
+     </skin>
+     <custom>
+        <fluidoSkin>
+        <topBarEnabled>true</topBarEnabled>
+        <sideBarEnabled>false</sideBarEnabled>
+        <searchEnabled>true</searchEnabled>
+        <gitHub>
+            <projectId>apache/tiles</projectId>
+            <ribbonOrientation>right</ribbonOrientation>
+            <ribbonColor>darkblue</ribbonColor>
+        </gitHub>
+        </fluidoSkin>
+     </custom>
+    <bannerLeft>
+        <name>Apache Tiles&#8482;</name>
+        <src>http://tiles.apache.org/images/logo.png</src>
+        <href>http://tiles.apache.org</href>
+    </bannerLeft>
+    <bannerRight>
+        <name>Apache Software Foundation</name>
+        <src>http://struts.apache.org/images/asf-logo.gif</src>
+        <href>http://www.apache.org</href>
+    </bannerRight>
+    <body>
+
+        <menu name="Apache Tiles&#8482;">
+            <item
+                   name="Welcome"
+                   href="../../index.html"/>
+            <item
+                    name="Tiles 3.0.x"
+                    href="../../framework/index.html"/>
+            <item
+                    name="Autotag 1.0.x"
+                    href="../../tiles-autotag/index.html"/>
+            <item
+                    name="Request 1.0.x"
+                    href="../../tiles-request/index.html"/>
+            <item
+                   name="Security bulletins"
+                   href="../security/index.html"/>
+            <item
+                   name="Download"
+                   href="http://tiles.apache.org/download.html"/>
+        </menu>
+
+        <menu ref="modules" />
+        <menu ref="reports" />
+
+        <footer>
+            <div class="row span12">
+                Apache Tiles, Tiles, Apache, the Apache feather logo, and the Apache Tiles
+                project logos are trademarks of The Apache Software Foundation.
+            </div>
+        </footer>
+    </body>
+</project>
diff --git a/Java-base/tiles/src/tiles-servlet/src/test/java/org/apache/tiles/web/startup/AbstractTilesInitializerServletTest.java b/Java-base/tiles/src/tiles-servlet/src/test/java/org/apache/tiles/web/startup/AbstractTilesInitializerServletTest.java
new file mode 100644
index 000000000..d2de305fa
--- /dev/null
+++ b/Java-base/tiles/src/tiles-servlet/src/test/java/org/apache/tiles/web/startup/AbstractTilesInitializerServletTest.java
@@ -0,0 +1,68 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.web.startup;
+
+import static org.easymock.classextension.EasyMock.*;
+
+import java.util.Enumeration;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+
+import org.apache.tiles.request.servlet.ServletApplicationContext;
+import org.apache.tiles.startup.TilesInitializer;
+import org.junit.Test;
+
+/**
+ * Tests {@link AbstractTilesInitializerServlet}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class AbstractTilesInitializerServletTest {
+
+    /**
+     * Test method for {@link org.apache.tiles.web.startup.AbstractTilesInitializerServlet#init()}.
+     * @throws ServletException If something goes wrong.
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testInit() throws ServletException {
+        AbstractTilesInitializerServlet servlet = createMockBuilder(AbstractTilesInitializerServlet.class).createMock();
+        TilesInitializer initializer = createMock(TilesInitializer.class);
+        ServletConfig config = createMock(ServletConfig.class);
+        ServletContext servletContext = createMock(ServletContext.class);
+        Enumeration<String> names = createMock(Enumeration.class);
+
+        expect(servlet.createTilesInitializer()).andReturn(initializer);
+        expect(config.getServletContext()).andReturn(servletContext);
+        expect(servletContext.getInitParameterNames()).andReturn(names);
+        expect(config.getInitParameterNames()).andReturn(names);
+        expect(names.hasMoreElements()).andReturn(false).times(2);
+        initializer.initialize(isA(ServletApplicationContext.class));
+        initializer.destroy();
+
+        replay(servlet, initializer, config, servletContext, names);
+        servlet.init(config);
+        servlet.destroy();
+        verify(servlet, initializer, config, servletContext, names);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-servlet/src/test/java/org/apache/tiles/web/startup/AbstractTilesListenerTest.java b/Java-base/tiles/src/tiles-servlet/src/test/java/org/apache/tiles/web/startup/AbstractTilesListenerTest.java
new file mode 100644
index 000000000..ca6f4aba2
--- /dev/null
+++ b/Java-base/tiles/src/tiles-servlet/src/test/java/org/apache/tiles/web/startup/AbstractTilesListenerTest.java
@@ -0,0 +1,61 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.web.startup;
+
+import static org.easymock.EasyMock.*;
+import static org.easymock.classextension.EasyMock.*;
+
+import javax.servlet.ServletContext;
+import javax.servlet.ServletContextEvent;
+
+import org.apache.tiles.request.servlet.ServletApplicationContext;
+import org.apache.tiles.startup.TilesInitializer;
+import org.junit.Test;
+
+/**
+ * Tests {@link AbstractTilesListener}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class AbstractTilesListenerTest {
+
+    /**
+     * Test method for {@link AbstractTilesListener#contextInitialized(ServletContextEvent)}.
+     */
+    @Test
+    public void testContextInitialized() {
+        AbstractTilesListener listener = createMockBuilder(AbstractTilesListener.class).createMock();
+        ServletContextEvent event = createMock(ServletContextEvent.class);
+        ServletContext servletContext = createMock(ServletContext.class);
+        TilesInitializer initializer = createMock(TilesInitializer.class);
+
+        expect(event.getServletContext()).andReturn(servletContext);
+        expect(listener.createTilesInitializer()).andReturn(initializer);
+        initializer.initialize(isA(ServletApplicationContext.class));
+        initializer.destroy();
+
+        replay(listener, event, servletContext, initializer);
+        listener.contextInitialized(event);
+        listener.contextDestroyed(event);
+        verify(listener, event, servletContext, initializer);
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-servlet/src/test/java/org/apache/tiles/web/startup/simple/SimpleTilesInitializerServletTest.java b/Java-base/tiles/src/tiles-servlet/src/test/java/org/apache/tiles/web/startup/simple/SimpleTilesInitializerServletTest.java
new file mode 100644
index 000000000..45d4cefbe
--- /dev/null
+++ b/Java-base/tiles/src/tiles-servlet/src/test/java/org/apache/tiles/web/startup/simple/SimpleTilesInitializerServletTest.java
@@ -0,0 +1,44 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.web.startup.simple;
+
+import static org.junit.Assert.*;
+
+import org.apache.tiles.startup.DefaultTilesInitializer;
+import org.junit.Test;
+
+/**
+ * Tests {@link SimpleTilesInitializerServlet}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class SimpleTilesInitializerServletTest {
+
+    /**
+     * Test method for {@link SimpleTilesInitializerServlet#createTilesInitializer()}.
+     */
+    @Test
+    public void testCreateTilesInitializer() {
+        SimpleTilesInitializerServlet servlet = new SimpleTilesInitializerServlet();
+        assertTrue(servlet.createTilesInitializer() instanceof DefaultTilesInitializer);
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-servlet/src/test/java/org/apache/tiles/web/startup/simple/SimpleTilesListenerTest.java b/Java-base/tiles/src/tiles-servlet/src/test/java/org/apache/tiles/web/startup/simple/SimpleTilesListenerTest.java
new file mode 100644
index 000000000..599a77a86
--- /dev/null
+++ b/Java-base/tiles/src/tiles-servlet/src/test/java/org/apache/tiles/web/startup/simple/SimpleTilesListenerTest.java
@@ -0,0 +1,44 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.web.startup.simple;
+
+import static org.junit.Assert.*;
+
+import org.apache.tiles.startup.DefaultTilesInitializer;
+import org.junit.Test;
+
+/**
+ * Tests {@link SimpleTilesListener}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class SimpleTilesListenerTest {
+
+    /**
+     * Test method for {@link org.apache.tiles.web.startup.simple.SimpleTilesListener#createTilesInitializer()}.
+     */
+    @Test
+    public void testCreateTilesInitializer() {
+        SimpleTilesListener servlet = new SimpleTilesListener();
+        assertTrue(servlet.createTilesInitializer() instanceof DefaultTilesInitializer);
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-servlet/src/test/java/org/apache/tiles/web/util/ServletContextAdapterTest.java b/Java-base/tiles/src/tiles-servlet/src/test/java/org/apache/tiles/web/util/ServletContextAdapterTest.java
new file mode 100644
index 000000000..d9109b8d7
--- /dev/null
+++ b/Java-base/tiles/src/tiles-servlet/src/test/java/org/apache/tiles/web/util/ServletContextAdapterTest.java
@@ -0,0 +1,456 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.web.util;
+
+import static org.easymock.EasyMock.*;
+import static org.easymock.classextension.EasyMock.*;
+import static org.junit.Assert.*;
+
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.Servlet;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests {@link ServletContextAdapter}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ServletContextAdapterTest {
+
+    /**
+     * The servlet configuration.
+     */
+    private ServletConfig config;
+
+    /**
+     * The servlet context.
+     */
+    private ServletContext servletContext;
+
+    /**
+     * First set of param names.
+     */
+    private Enumeration<String> names1;
+
+    /**
+     * Second set of param names.
+     */
+    private Enumeration<String> names2;
+
+    /**
+     * Sets up the test.
+     */
+    @SuppressWarnings("unchecked")
+    @Before
+    public void setUp() {
+        config = createMock(ServletConfig.class);
+        servletContext = createMock(ServletContext.class);
+        names1 = createMock(Enumeration.class);
+        names2 = createMock(Enumeration.class);
+
+        expect(config.getServletContext()).andReturn(servletContext);
+        expect(names1.hasMoreElements()).andReturn(true);
+        expect(names1.nextElement()).andReturn("one");
+        expect(names1.hasMoreElements()).andReturn(true);
+        expect(names1.nextElement()).andReturn("two");
+        expect(names1.hasMoreElements()).andReturn(false);
+        expect(names2.hasMoreElements()).andReturn(true);
+        expect(names2.nextElement()).andReturn("two");
+        expect(names2.hasMoreElements()).andReturn(true);
+        expect(names2.nextElement()).andReturn("three");
+        expect(names2.hasMoreElements()).andReturn(false);
+        expect(servletContext.getInitParameterNames()).andReturn(names1);
+        expect(servletContext.getInitParameter("one")).andReturn("value1");
+        expect(servletContext.getInitParameter("two")).andReturn("value2");
+        expect(config.getInitParameterNames()).andReturn(names2);
+        expect(config.getInitParameter("two")).andReturn("otherValue2");
+        expect(config.getInitParameter("three")).andReturn("otherValue3");
+
+        replay(names1, names2);
+    }
+
+    /**
+     * Tears down the test.
+     */
+    @After
+    public void tearDown() {
+        verify(config, servletContext, names1, names2);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.web.util.ServletContextAdapter#getContext(java.lang.String)}.
+     */
+    @Test
+    public void testGetContext() {
+        ServletContext otherContext = createMock(ServletContext.class);
+        expect(servletContext.getContext("whatever")).andReturn(otherContext);
+
+        replay(servletContext, config, otherContext);
+        ServletContextAdapter adapter = new ServletContextAdapter(config);
+        assertEquals(otherContext, adapter.getContext("whatever"));
+        verify(otherContext);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.web.util.ServletContextAdapter#getMajorVersion()}.
+     */
+    @Test
+    public void testGetMajorVersion() {
+        expect(servletContext.getMajorVersion()).andReturn(2);
+
+        replay(servletContext, config);
+        ServletContextAdapter adapter = new ServletContextAdapter(config);
+        assertEquals(2, adapter.getMajorVersion());
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.web.util.ServletContextAdapter#getMinorVersion()}.
+     */
+    @Test
+    public void testGetMinorVersion() {
+        expect(servletContext.getMinorVersion()).andReturn(5);
+
+        replay(servletContext, config);
+        ServletContextAdapter adapter = new ServletContextAdapter(config);
+        assertEquals(5, adapter.getMinorVersion());
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.web.util.ServletContextAdapter#getMimeType(java.lang.String)}.
+     */
+    @Test
+    public void testGetMimeType() {
+        expect(servletContext.getMimeType("whatever")).andReturn("mymime");
+
+        replay(servletContext, config);
+        ServletContextAdapter adapter = new ServletContextAdapter(config);
+        assertEquals("mymime", adapter.getMimeType("whatever"));
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.web.util.ServletContextAdapter#getResourcePaths(java.lang.String)}.
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testGetResourcePaths() {
+        Set<URL> urls = createMock(Set.class);
+
+        expect(servletContext.getResourcePaths("whatever")).andReturn(urls);
+
+        replay(servletContext, config, urls);
+        ServletContextAdapter adapter = new ServletContextAdapter(config);
+        assertEquals(urls, adapter.getResourcePaths("whatever"));
+        verify(urls);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.web.util.ServletContextAdapter#getResource(java.lang.String)}.
+     * @throws MalformedURLException If something goes wrong.
+     */
+    @Test
+    public void testGetResource() throws MalformedURLException {
+        URL url = new URL("file:///temporary");
+
+        expect(servletContext.getResource("whatever")).andReturn(url);
+
+        replay(servletContext, config);
+        ServletContextAdapter adapter = new ServletContextAdapter(config);
+        assertEquals(url, adapter.getResource("whatever"));
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.web.util.ServletContextAdapter#getResourceAsStream(java.lang.String)}.
+     */
+    @Test
+    public void testGetResourceAsStream() {
+        InputStream is = createMock(InputStream.class);
+
+        expect(servletContext.getResourceAsStream("whatever")).andReturn(is);
+
+        replay(servletContext, config, is);
+        ServletContextAdapter adapter = new ServletContextAdapter(config);
+        assertEquals(is, adapter.getResourceAsStream("whatever"));
+        verify(is);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.web.util.ServletContextAdapter#getRequestDispatcher(java.lang.String)}.
+     */
+    @Test
+    public void testGetRequestDispatcher() {
+        RequestDispatcher is = createMock(RequestDispatcher.class);
+
+        expect(servletContext.getRequestDispatcher("whatever")).andReturn(is);
+
+        replay(servletContext, config, is);
+        ServletContextAdapter adapter = new ServletContextAdapter(config);
+        assertEquals(is, adapter.getRequestDispatcher("whatever"));
+        verify(is);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.web.util.ServletContextAdapter#getNamedDispatcher(java.lang.String)}.
+     */
+    @Test
+    public void testGetNamedDispatcher() {
+        RequestDispatcher is = createMock(RequestDispatcher.class);
+
+        expect(servletContext.getNamedDispatcher("whatever")).andReturn(is);
+
+        replay(servletContext, config, is);
+        ServletContextAdapter adapter = new ServletContextAdapter(config);
+        assertEquals(is, adapter.getNamedDispatcher("whatever"));
+        verify(is);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.web.util.ServletContextAdapter#getServlet(java.lang.String)}.
+     * @throws ServletException If something goes wrong.
+     */
+    @SuppressWarnings("deprecation")
+    @Test
+    public void testGetServlet() throws ServletException {
+        Servlet is = createMock(Servlet.class);
+
+        expect(servletContext.getServlet("whatever")).andReturn(is);
+
+        replay(servletContext, config, is);
+        ServletContextAdapter adapter = new ServletContextAdapter(config);
+        assertEquals(is, adapter.getServlet("whatever"));
+        verify(is);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.web.util.ServletContextAdapter#getServlets()}.
+     */
+    @SuppressWarnings({ "deprecation", "unchecked" })
+    @Test
+    public void testGetServlets() {
+        Enumeration<Servlet> is = createMock(Enumeration.class);
+
+        expect(servletContext.getServlets()).andReturn(is);
+
+        replay(servletContext, config, is);
+        ServletContextAdapter adapter = new ServletContextAdapter(config);
+        assertEquals(is, adapter.getServlets());
+        verify(is);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.web.util.ServletContextAdapter#getServletNames()}.
+     */
+    @SuppressWarnings({ "deprecation", "unchecked" })
+    @Test
+    public void testGetServletNames() {
+        Enumeration<String> is = createMock(Enumeration.class);
+
+        expect(servletContext.getServletNames()).andReturn(is);
+
+        replay(servletContext, config, is);
+        ServletContextAdapter adapter = new ServletContextAdapter(config);
+        assertEquals(is, adapter.getServletNames());
+        verify(is);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.web.util.ServletContextAdapter#log(java.lang.String)}.
+     */
+    @Test
+    public void testLogString() {
+        servletContext.log("whatever");
+
+        replay(servletContext, config);
+        ServletContextAdapter adapter = new ServletContextAdapter(config);
+        adapter.log("whatever");
+    }
+
+    /**
+     * Test method for {@link ServletContextAdapter#log(java.lang.Exception, java.lang.String)}.
+     */
+    @SuppressWarnings("deprecation")
+    @Test
+    public void testLogExceptionString() {
+        Exception e = new Exception("It does not matter");
+        servletContext.log(e, "whatever");
+
+        replay(servletContext, config);
+        ServletContextAdapter adapter = new ServletContextAdapter(config);
+        adapter.log(e, "whatever");
+    }
+
+    /**
+     * Test method for {@link ServletContextAdapter#log(java.lang.String, java.lang.Throwable)}.
+     */
+    @Test
+    public void testLogStringThrowable() {
+        Throwable e = new Throwable("It does not matter");
+        servletContext.log("whatever", e);
+
+        replay(servletContext, config);
+        ServletContextAdapter adapter = new ServletContextAdapter(config);
+        adapter.log("whatever", e);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.web.util.ServletContextAdapter#getRealPath(java.lang.String)}.
+     */
+    @Test
+    public void testGetRealPath() {
+        expect(servletContext.getRealPath("whatever")).andReturn("mypath");
+
+        replay(servletContext, config);
+        ServletContextAdapter adapter = new ServletContextAdapter(config);
+        assertEquals("mypath", adapter.getRealPath("whatever"));
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.web.util.ServletContextAdapter#getServerInfo()}.
+     */
+    @Test
+    public void testGetServerInfo() {
+        expect(servletContext.getServerInfo()).andReturn("info");
+
+        replay(servletContext, config);
+        ServletContextAdapter adapter = new ServletContextAdapter(config);
+        assertEquals("info", adapter.getServerInfo());
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.web.util.ServletContextAdapter#getInitParameter(java.lang.String)}.
+     */
+    @Test
+    public void testGetInitParameter() {
+        replay(servletContext, config);
+        ServletContextAdapter adapter = new ServletContextAdapter(config);
+        assertEquals("value1", adapter.getInitParameter("one"));
+        assertEquals("otherValue2", adapter.getInitParameter("two"));
+        assertEquals("otherValue3", adapter.getInitParameter("three"));
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.web.util.ServletContextAdapter#getInitParameterNames()}.
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testGetInitParameterNames() {
+        replay(servletContext, config);
+        ServletContextAdapter adapter = new ServletContextAdapter(config);
+        Set<String> names = new HashSet<String>();
+        names.add("one");
+        names.add("two");
+        names.add("three");
+        for (Enumeration<String> enumeration = adapter.getInitParameterNames(); enumeration.hasMoreElements();) {
+            String name = enumeration.nextElement();
+            assertTrue(names.remove(name));
+        }
+        assertTrue(names.isEmpty());
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.web.util.ServletContextAdapter#getAttribute(java.lang.String)}.
+     */
+    @Test
+    public void testGetAttribute() {
+        expect(servletContext.getAttribute("whatever")).andReturn("value");
+
+        replay(servletContext, config);
+        ServletContextAdapter adapter = new ServletContextAdapter(config);
+        assertEquals("value", adapter.getAttribute("whatever"));
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.web.util.ServletContextAdapter#getAttributeNames()}.
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testGetAttributeNames() {
+        Enumeration<String> is = createMock(Enumeration.class);
+
+        expect(servletContext.getAttributeNames()).andReturn(is);
+
+        replay(servletContext, config, is);
+        ServletContextAdapter adapter = new ServletContextAdapter(config);
+        assertEquals(is, adapter.getAttributeNames());
+        verify(is);
+    }
+
+    /**
+     * Test method for {@link ServletContextAdapter#setAttribute(java.lang.String, java.lang.Object)}.
+     */
+    @Test
+    public void testSetAttribute() {
+        servletContext.setAttribute("whatever", "value");
+
+        replay(servletContext, config);
+        ServletContextAdapter adapter = new ServletContextAdapter(config);
+        adapter.setAttribute("whatever", "value");
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.web.util.ServletContextAdapter#removeAttribute(java.lang.String)}.
+     */
+    @Test
+    public void testRemoveAttribute() {
+        servletContext.removeAttribute("whatever");
+
+        replay(servletContext, config);
+        ServletContextAdapter adapter = new ServletContextAdapter(config);
+        adapter.removeAttribute("whatever");
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.web.util.ServletContextAdapter#getServletContextName()}.
+     */
+    @Test
+    public void testGetServletContextName() {
+        expect(servletContext.getServletContextName()).andReturn("value");
+
+        replay(servletContext, config);
+        ServletContextAdapter adapter = new ServletContextAdapter(config);
+        assertEquals("value", adapter.getServletContextName());
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.web.util.ServletContextAdapter#getContextPath()}.
+     */
+    @Test
+    public void testGetContextPath() {
+        expect(servletContext.getContextPath()).andReturn("value");
+
+        replay(servletContext, config);
+        ServletContextAdapter adapter = new ServletContextAdapter(config);
+        assertEquals("value", adapter.getContextPath());
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-servlet/src/test/java/org/apache/tiles/web/util/TilesDecorationFilterTest.java b/Java-base/tiles/src/tiles-servlet/src/test/java/org/apache/tiles/web/util/TilesDecorationFilterTest.java
new file mode 100644
index 000000000..6b1e41141
--- /dev/null
+++ b/Java-base/tiles/src/tiles-servlet/src/test/java/org/apache/tiles/web/util/TilesDecorationFilterTest.java
@@ -0,0 +1,151 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.web.util;
+
+import static org.easymock.EasyMock.*;
+import static org.easymock.classextension.EasyMock.*;
+
+import java.io.IOException;
+import java.util.Enumeration;
+import java.util.Map;
+
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.tiles.request.ApplicationAccess;
+import org.apache.tiles.AttributeContext;
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.servlet.ServletRequest;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests {@link TilesDecorationFilter}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TilesDecorationFilterTest {
+
+    /**
+     * The filter configuration.
+     */
+    private FilterConfig config;
+
+    /**
+     * The servlet context.
+     */
+    private ServletContext servletContext;
+
+    /**
+     * The filter to test.
+     */
+    private TilesDecorationFilter filter;
+
+    /**
+     * Sets up the test.
+     * @throws ServletException If something goes wrong.
+     */
+    @SuppressWarnings("unchecked")
+    @Before
+    public void setUp() throws ServletException {
+        config = createMock(FilterConfig.class);
+        servletContext = createMock(ServletContext.class);
+        Enumeration<String> names = createMock(Enumeration.class);
+
+        expect(config.getServletContext()).andReturn(servletContext);
+        expect(config.getInitParameter(TilesDecorationFilter.CONTAINER_KEY_INIT_PARAMETER)).andReturn("key");
+        expect(config.getInitParameter("attribute-name")).andReturn("attributeKey");
+        expect(config.getInitParameter("definition")).andReturn("definitionKey");
+        expect(config.getInitParameter("prevent-token")).andReturn("tokenKey");
+        expect(names.hasMoreElements()).andReturn(true);
+        expect(names.nextElement()).andReturn("definition(hello*)");
+        expect(names.hasMoreElements()).andReturn(false);
+        expect(config.getInitParameterNames()).andReturn(names);
+        expect(config.getInitParameter("definition(hello*)")).andReturn("alternateDef");
+        expect(config.getInitParameter("mutator")).andReturn(CustomAttributeMutator.class.getName());
+
+        replay(config, names);
+        filter = new TilesDecorationFilter();
+        filter.init(config);
+        verify(names);
+    }
+
+    /**
+     * Tears down the test.
+     */
+    @After
+    public void tearDown() {
+        verify(config, servletContext);
+    }
+
+    /**
+     * Test method for {@link TilesDecorationFilter#doFilter(ServletRequest, ServletResponse, FilterChain)}.
+     * @throws ServletException If something goes wrong
+     * @throws IOException If something goes wrong.
+     */
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testDoFilter() throws IOException, ServletException {
+        HttpServletRequest request = createMock(HttpServletRequest.class);
+        HttpServletResponse response = createMock(HttpServletResponse.class);
+        FilterChain chain = createMock(FilterChain.class);
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        Map<String, Object> applicationScope = createMock(Map.class);
+        TilesContainer container = createMock(TilesContainer.class);
+        AttributeContext attributeContext = createMock(AttributeContext.class);
+
+        expect(request.getAttribute("org.apache.tiles.decoration.PREVENT:tokenKey")).andReturn(null);
+        expect(servletContext.getAttribute(ApplicationAccess.APPLICATION_CONTEXT_ATTRIBUTE))
+                .andReturn(applicationContext);
+        expect(applicationContext.getApplicationScope()).andReturn(applicationScope);
+        expect(applicationScope.get("key")).andReturn(container);
+        expect(container.getAttributeContext(isA(ServletRequest.class))).andReturn(attributeContext);
+        request.setAttribute("org.apache.tiles.decoration.PREVENT:tokenKey", true);
+        expect(request.getAttribute("javax.servlet.include.servlet_path")).andReturn(null);
+        expect(request.getServletPath()).andReturn("/tiles");
+        container.render(eq("definitionKey"), isA(ServletRequest.class));
+        chain.doFilter(request, response);
+
+        replay(servletContext, request, response, chain, applicationContext,
+                applicationScope, container, attributeContext);
+        filter.doFilter(request, response, chain);
+        verify(request, response, chain, applicationContext, applicationScope, container, attributeContext);
+    }
+
+    /**
+     * Internal mutator for testing.
+     *
+     */
+    public static class CustomAttributeMutator implements AttributeContextMutator {
+
+        @Override
+        public void mutate(AttributeContext context,
+                javax.servlet.ServletRequest request) {
+            // Does nothing.
+        }
+    }
+}
diff --git a/Java-base/tiles/src/tiles-template/pom.xml b/Java-base/tiles/src/tiles-template/pom.xml
new file mode 100644
index 000000000..016f59980
--- /dev/null
+++ b/Java-base/tiles/src/tiles-template/pom.xml
@@ -0,0 +1,104 @@
+<?xml version="1.0"?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.apache.tiles</groupId>
+  <artifactId>tiles-template</artifactId>
+  <name>Tiles - Template Technologies Support</name>
+  <description>Common code for integration of Tiles for different templating technologies.</description>
+  <parent>
+    <artifactId>tiles-parent</artifactId>
+    <groupId>org.apache.tiles</groupId>
+    <version>3.1-SNAPSHOT</version>
+  </parent>
+  <properties>
+      <!-- decrease this whenever possible -->
+      <checkstyle.maxAllowedViolations>2</checkstyle.maxAllowedViolations>
+  </properties>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.tiles.autotag.plugin</groupId>
+        <artifactId>maven-autotag-plugin</artifactId>
+        <version>${tiles.autotag.version}</version>
+        <executions>
+            <execution>
+                <goals>
+                    <goal>create-descriptor</goal>
+                </goals>
+                <configuration>
+                    <name>tiles</name>
+                    <requestClass>org.apache.tiles.request.Request</requestClass>
+                </configuration>
+            </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.tiles</groupId>
+      <artifactId>tiles-api</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>jcl-over-slf4j</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-jdk14</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.easymock</groupId>
+      <artifactId>easymock</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.easymock</groupId>
+      <artifactId>easymockclassextension</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+        <groupId>org.apache.tiles</groupId>
+        <artifactId>tiles-autotag-core-runtime</artifactId>
+        <version>${tiles.autotag.version}</version>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/AddAttributeModel.java b/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/AddAttributeModel.java
new file mode 100644
index 000000000..7fc3a6558
--- /dev/null
+++ b/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/AddAttributeModel.java
@@ -0,0 +1,118 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.template;
+
+import java.io.IOException;
+import java.util.Deque;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.Expression;
+import org.apache.tiles.ListAttribute;
+import org.apache.tiles.autotag.core.runtime.ModelBody;
+import org.apache.tiles.request.Request;
+
+/**
+ * <p>
+ * <strong>Add an element to the surrounding list. Equivalent to 'putAttribute',
+ * but for list element.</strong>
+ * </p>
+ *
+ * <p>
+ * Add an element to the surrounding list. This tag can only be used inside
+ * 'putListAttribute' or 'addListAttribute' tags. Value can come from a direct
+ * assignment (value="aValue")
+ * </p>
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public class AddAttributeModel {
+
+    /**
+     * Executes the operation.
+     * @param value The value of the attribute. Use this parameter, or
+     * expression, or body.
+     * @param expression The expression to calculate the value from. Use this
+     * parameter, or value, or body.
+     * @param role A comma-separated list of roles. If present, the attribute
+     * will be rendered only if the current user belongs to one of the roles.
+     * @param type The type (renderer) of the attribute.
+     * @param request The request.
+     * @param modelBody The body.
+     * @throws IOException If the body cannot be correctly evaluated.
+     * @since 2.2.0
+     */
+    public void execute(Object value, String expression, String role,
+            String type, Request request, ModelBody modelBody)
+            throws IOException {
+        Attribute attribute = new Attribute();
+        Deque<Object> composeStack = ComposeStackUtil.getComposeStack(request);
+        composeStack.push(attribute);
+        String body = modelBody.evaluateAsString();
+        attribute = (Attribute) composeStack.pop();
+        addAttributeToList(attribute, composeStack, value, expression, body,
+                role, type);
+    }
+
+    /**
+     * Adds the attribute to the containing list attribute.
+     *
+     * @param attribute The attribute to add to the list attribute.
+     * @param composeStack The composing stack.
+     * @param value The value of the attribute. Use this parameter, or
+     * expression, or body.
+     * @param expression The expression to calculate the value from. Use this
+     * parameter, or value, or body.
+     * @param body The body of the tag. Use this parameter, or value, or
+     * expression.
+     * @param role A comma-separated list of roles. If present, the attribute
+     * will be rendered only if the current user belongs to one of the roles.
+     * @param type The type (renderer) of the attribute.
+     * @since 2.2.0
+     */
+    private void addAttributeToList(Attribute attribute,
+            Deque<Object> composeStack, Object value, String expression,
+            String body, String role, String type) {
+        ListAttribute listAttribute = (ListAttribute) ComposeStackUtil
+                .findAncestorWithClass(composeStack, ListAttribute.class);
+
+        if (listAttribute == null) {
+            throw new NullPointerException("There is no ListAttribute in the stack");
+        }
+        if (value != null) {
+            attribute.setValue(value);
+        } else if (attribute.getValue() == null && body != null) {
+            attribute.setValue(body);
+        }
+        if (expression != null) {
+            attribute.setExpressionObject(Expression
+                    .createExpressionFromDescribedExpression(expression));
+        }
+        if (role != null) {
+            attribute.setRole(role);
+        }
+        if (type != null) {
+            attribute.setRenderer(type);
+        }
+        listAttribute.add(attribute);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/AddListAttributeModel.java b/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/AddListAttributeModel.java
new file mode 100644
index 000000000..12cb1bef3
--- /dev/null
+++ b/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/AddListAttributeModel.java
@@ -0,0 +1,64 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.template;
+
+import java.io.IOException;
+import java.util.Deque;
+
+import org.apache.tiles.ListAttribute;
+import org.apache.tiles.autotag.core.runtime.ModelBody;
+import org.apache.tiles.request.Request;
+
+/**
+ * <p>
+ * <strong>Declare a list that will be pass as an attribute. </strong>
+ * </p>
+ * <p>
+ * Declare a list that will be pass as an attribute . List elements are added
+ * using the tag 'addAttribute' or 'addListAttribute'. This tag can only be used
+ * inside 'insertTemplate', 'insertDefinition' or 'definition' tag.
+ * </p>
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public class AddListAttributeModel {
+
+    /**
+     * Executes the model.
+     *
+     * @param role The comma-separated list of roles that can use the list attribute.
+     * @param request The request.
+     * @param modelBody The body.
+     * @throws IOException If the body cannot be evaluated.
+     */
+    public void execute(String role, Request request, ModelBody modelBody) throws IOException {
+        Deque<Object> composeStack = ComposeStackUtil.getComposeStack(request);
+        ListAttribute listAttribute = new ListAttribute();
+        listAttribute.setRole(role);
+        composeStack.push(listAttribute);
+        modelBody.evaluateWithoutWriting();
+        listAttribute = (ListAttribute) composeStack.pop();
+        ListAttribute parent = (ListAttribute) composeStack.peek();
+        parent.add(listAttribute);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/AttributeResolver.java b/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/AttributeResolver.java
new file mode 100644
index 000000000..3815ddcb6
--- /dev/null
+++ b/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/AttributeResolver.java
@@ -0,0 +1,55 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.template;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.request.Request;
+
+/**
+ * Resolves an attribute, depending on the given parameters.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public interface AttributeResolver {
+
+    /**
+     * Computes the attribute.
+     *
+     * @param container The Tiles container to use.
+     * @param attribute The attribute to return immediately, if not null.
+     * @param name The name of the attribute.
+     * @param role A comma-separated list of roles. If present, the attribute
+     * will be rendered only if the current user belongs to one of the roles.
+     * @param ignore If <code>true</code> if the computed attribute is null, this problem will be ignored.
+     * @param defaultValue The default value of the attribute. To use only if the attribute was not computed.
+     * @param defaultValueRole The default comma-separated list of roles. To use only if the attribute was not computed.
+     * @param defaultValueType The default type of the attribute. To use only if the attribute was not computed.
+     * @param request TODO
+     * @return The computed attribute.
+     * @since 2.2.0
+     */
+    Attribute computeAttribute(TilesContainer container, Attribute attribute,
+            String name, String role, boolean ignore,
+            Object defaultValue, String defaultValueRole, String defaultValueType, Request request);
+}
diff --git a/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/ComposeStackUtil.java b/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/ComposeStackUtil.java
new file mode 100644
index 000000000..00e472ca1
--- /dev/null
+++ b/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/ComposeStackUtil.java
@@ -0,0 +1,86 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.template;
+
+import java.util.Deque;
+import java.util.LinkedList;
+import java.util.Map;
+
+import org.apache.tiles.request.Request;
+
+/**
+ * Utilities to work with compose stacks.
+ *
+ * @version $Rev$ $Date$
+ * @since 3.0.0
+ */
+public final class ComposeStackUtil {
+
+    /**
+     * The name of the attribute that holds the compose stack.
+     */
+    public static final String COMPOSE_STACK_ATTRIBUTE_NAME = "org.apache.tiles.template.COMPOSE_STACK";
+
+    /**
+     * Private constructor to avoid instantiation.
+     */
+    private ComposeStackUtil() {
+
+    }
+
+    /**
+     * Finds the first ancestor in the stack, that is assignable to the given class.
+     *
+     * @param composeStack The compose stack to evaluate.
+     * @param clazz The class to check.
+     * @return The first ancestor that is assignable to the class, or null if not found.
+     * @since 3.0.0
+     */
+    public static Object findAncestorWithClass(Deque<Object> composeStack, Class<?> clazz) {
+        for (Object obj : composeStack) {
+            if (clazz.isAssignableFrom(obj.getClass())) {
+                return obj;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns the current compose stack, or creates a new one if not present.
+     *
+     * @param request The request.
+     * @return The compose stack.
+     * @since 3.0.0
+     */
+    @SuppressWarnings("unchecked")
+    public static Deque<Object> getComposeStack(Request request) {
+        Map<String, Object> requestScope = request.getContext("request");
+        Deque<Object> composeStack = (Deque<Object>) requestScope
+                .get(COMPOSE_STACK_ATTRIBUTE_NAME);
+        if (composeStack == null) {
+            composeStack = new LinkedList<Object>();
+            requestScope.put(ComposeStackUtil.COMPOSE_STACK_ATTRIBUTE_NAME, composeStack);
+        }
+        return composeStack;
+    }
+}
diff --git a/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/DefaultAttributeResolver.java b/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/DefaultAttributeResolver.java
new file mode 100644
index 000000000..c35ca5917
--- /dev/null
+++ b/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/DefaultAttributeResolver.java
@@ -0,0 +1,83 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.template;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.AttributeContext;
+import org.apache.tiles.Expression;
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.request.Request;
+
+/**
+ * The default implementation of AttributeResolver.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public class DefaultAttributeResolver implements AttributeResolver {
+
+    /** {@inheritDoc} */
+    public Attribute computeAttribute(TilesContainer container, Attribute attribute,
+            String name, String role, boolean ignore,
+            Object defaultValue, String defaultValueRole, String defaultValueType, Request request) {
+        if (attribute == null) {
+            AttributeContext evaluatingContext = container
+                    .getAttributeContext(request);
+            attribute = evaluatingContext.getAttribute(name);
+            if (attribute == null) {
+                attribute = computeDefaultAttribute(defaultValue,
+                        defaultValueRole, defaultValueType);
+                if (attribute == null && !ignore) {
+                    throw new NoSuchAttributeException("Attribute '" + name
+                            + "' not found.");
+                }
+            }
+        }
+        if (attribute != null && role != null && !"".equals(role.trim())) {
+            attribute = new Attribute(attribute);
+            attribute.setRole(role);
+        }
+        return attribute;
+    }
+
+    /**
+     * Computes the default attribute.
+     *
+     * @param defaultValue The default value of the attribute.
+     * @param defaultValueRole The default role of tha attribute.
+     * @param defaultValueType The default type of the attribute.
+     * @return The default attribute.
+     */
+    private Attribute computeDefaultAttribute(Object defaultValue,
+            String defaultValueRole, String defaultValueType) {
+        Attribute attribute = null;
+        if (defaultValue != null) {
+            if (defaultValue instanceof Attribute) {
+                attribute = (Attribute) defaultValue;
+            } else if (defaultValue instanceof String) {
+                attribute = new Attribute(defaultValue, (Expression) null,
+                        defaultValueRole, defaultValueType);
+            }
+        }
+        return attribute;
+    }
+}
diff --git a/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/DefinitionModel.java b/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/DefinitionModel.java
new file mode 100644
index 000000000..0953dbc13
--- /dev/null
+++ b/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/DefinitionModel.java
@@ -0,0 +1,133 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.template;
+
+import java.io.IOException;
+import java.util.Deque;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.Definition;
+import org.apache.tiles.access.TilesAccess;
+import org.apache.tiles.autotag.core.runtime.ModelBody;
+import org.apache.tiles.autotag.core.runtime.annotation.Parameter;
+import org.apache.tiles.mgmt.MutableTilesContainer;
+import org.apache.tiles.request.Request;
+
+/**
+ * <p>
+ * <strong>Create a definition at runtime. </strong>
+ * </p>
+ * <p>
+ * Create a new definition at runtime. Newly created definition will be
+ * available across the entire request.
+ * </p>
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public class DefinitionModel {
+
+    /**
+     * Executes the operation.
+     *
+     * @param name The name of the definition to create. If not specified, an
+     * anonymous definition will be created.
+     * @param template The template of this definition.
+     * @param role A comma-separated list of roles. If present, the definition
+     * will be rendered only if the current user belongs to one of the roles.
+     * @param extendsParam The definition name that this definition extends.
+     * @param preparer The preparer to use to invoke before the definition is
+     * rendered.
+     * @param request The request.
+     * @param modelBody The body.
+     * @throws IOException If something goes wrong.
+     * @since 2.2.0
+     */
+    public void execute(String name, String template, String role,
+            @Parameter(name = "extends") String extendsParam, String preparer,
+            Request request, ModelBody modelBody) throws IOException {
+        Deque<Object> composeStack = ComposeStackUtil
+                .getComposeStack(request);
+        Definition definition = createDefinition(name, template, role,
+                extendsParam, preparer);
+        composeStack.push(definition);
+        modelBody.evaluateWithoutWriting();
+        MutableTilesContainer container = (MutableTilesContainer) TilesAccess
+                .getCurrentContainer(request);
+        definition = (Definition) composeStack.pop();
+        registerDefinition(definition, container, composeStack, request);
+    }
+
+    /**
+     * Creates the definition to store.
+     *
+     * @param name The name of the definition to create. If not specified, an
+     * anonymous definition will be created.
+     * @param template The template of this definition.
+     * @param role A comma-separated list of roles. If present, the definition
+     * will be rendered only if the current user belongs to one of the roles.
+     * @param extendsParam The definition name that this definition extends.
+     * @param preparer The preparer to use to invoke before the definition is
+     * rendered.
+     * @return The created definition.
+     */
+    private Definition createDefinition(String name, String template,
+            String role, String extendsParam, String preparer) {
+        Definition definition = new Definition();
+        definition.setName(name);
+        Attribute templateAttribute = Attribute
+                .createTemplateAttribute(template);
+        templateAttribute.setRole(role);
+        definition.setTemplateAttribute(templateAttribute);
+        definition.setExtends(extendsParam);
+        definition.setPreparer(preparer);
+        return definition;
+    }
+
+    /**
+     * Registers a definition in the container.
+     *
+     * @param definition The definition to register.
+     * @param container The container into which the definition will be
+     * registered.
+     * @param composeStack The compose stack,
+     * @param request The request.
+     */
+    private void registerDefinition(Definition definition,
+            MutableTilesContainer container, Deque<Object> composeStack,
+            Request request) {
+        container.register(definition, request);
+
+        if (composeStack.isEmpty()) {
+            return;
+        }
+
+        Object obj = composeStack.peek();
+        if (obj instanceof Attribute) {
+            Attribute attribute = (Attribute) obj;
+            attribute.setValue(definition.getName());
+            if (attribute.getRenderer() == null) {
+                attribute.setRenderer("definition");
+            }
+        }
+    }
+}
diff --git a/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/GetAsStringModel.java b/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/GetAsStringModel.java
new file mode 100644
index 000000000..1fc829528
--- /dev/null
+++ b/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/GetAsStringModel.java
@@ -0,0 +1,197 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.template;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Deque;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.access.TilesAccess;
+import org.apache.tiles.autotag.core.runtime.ModelBody;
+import org.apache.tiles.autotag.core.runtime.annotation.Parameter;
+import org.apache.tiles.request.Request;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * <p>
+ * <strong> Render the value of the specified template attribute to the current
+ * Writer</strong>
+ * </p>
+ *
+ * <p>
+ * Retrieve the value of the specified template attribute property, and render
+ * it to the current Writer as a String. The usual toString() conversions is
+ * applied on found value.
+ * </p>
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public class GetAsStringModel {
+
+    /**
+     * The logging object.
+     */
+    private Logger log = LoggerFactory.getLogger(getClass());
+
+    /**
+     * The attribute resolver to use.
+     */
+    private AttributeResolver attributeResolver;
+
+    /**
+     * Constructor that uses the defaut attribute resolver.
+     *
+     * @since 3.0.0
+     */
+    public GetAsStringModel() {
+        this(new DefaultAttributeResolver());
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param attributeResolver The attribute resolver to use.
+     * @since 2.2.0
+     */
+    public GetAsStringModel(AttributeResolver attributeResolver) {
+        this.attributeResolver = attributeResolver;
+    }
+
+    /**
+     * Executes the operation.
+     * @param ignore If <code>true</code>, if an exception happens during
+     * rendering, of if the attribute is null, the problem will be ignored.
+     * @param preparer The preparer to invoke before rendering the attribute.
+     * @param role A comma-separated list of roles. If present, the attribute
+     * will be rendered only if the current user belongs to one of the roles.
+     * @param defaultValue The default value of the attribute. To use only if
+     * the attribute was not computed.
+     * @param defaultValueRole The default comma-separated list of roles. To use
+     * only if the attribute was not computed.
+     * @param defaultValueType The default type of the attribute. To use only if
+     * the attribute was not computed.
+     * @param name The name of the attribute.
+     * @param value The attribute to use immediately, if not null.
+     * @param request The request.
+     * @param modelBody The body.
+     * @throws IOException If an I/O error happens during rendering.
+     * @since 2.2.0
+     */
+    public void execute(boolean ignore, String preparer, String role,
+            Object defaultValue, String defaultValueRole,
+            String defaultValueType, @Parameter(required = true) String name,
+            Attribute value, Request request, ModelBody modelBody)
+            throws IOException {
+        TilesContainer container = TilesAccess.getCurrentContainer(request);
+        Deque<Object> composeStack = ComposeStackUtil.getComposeStack(request);
+        Attribute attribute = resolveAttribute(container, ignore, preparer,
+                role, defaultValue, defaultValueRole, defaultValueType, name,
+                value, request);
+        if (attribute != null) {
+            composeStack.push(attribute);
+        }
+        modelBody.evaluateWithoutWriting();
+        container = TilesAccess.getCurrentContainer(request);
+        Writer writer = request.getWriter();
+        if (attribute != null) {
+            attribute = (Attribute) composeStack.pop();
+        }
+        renderAttribute(attribute, container, writer, ignore, request);
+    }
+
+    /**
+     * Resolves the attribute. and starts the context.
+     *
+     * @param container The Tiles container to use.
+     * @param ignore If <code>true</code>, if an exception happens during
+     * rendering, of if the attribute is null, the problem will be ignored.
+     * @param preparer The preparer to invoke before rendering the attribute.
+     * @param role A comma-separated list of roles. If present, the attribute
+     * will be rendered only if the current user belongs to one of the roles.
+     * @param defaultValue The default value of the attribute. To use only if
+     * the attribute was not computed.
+     * @param defaultValueRole The default comma-separated list of roles. To use
+     * only if the attribute was not computed.
+     * @param defaultValueType The default type of the attribute. To use only if
+     * the attribute was not computed.
+     * @param name The name of the attribute.
+     * @param value The attribute to use immediately, if not null.
+     * @param request The request.
+     * @return The resolved attribute.
+     */
+    private Attribute resolveAttribute(TilesContainer container,
+            boolean ignore, String preparer, String role, Object defaultValue,
+            String defaultValueRole, String defaultValueType, String name,
+            Attribute value, Request request) {
+        if (preparer != null) {
+            container.prepare(preparer, request);
+        }
+        Attribute attribute = attributeResolver.computeAttribute(container,
+                value, name, role, ignore, defaultValue, defaultValueRole,
+                defaultValueType, request);
+        container.startContext(request);
+        return attribute;
+    }
+
+    /**
+     * Renders the attribute as a string.
+     *
+     * @param attribute The attribute to use, previously resolved.
+     * @param container The Tiles container to use.
+     * @param writer The writer into which the attribute will be written.
+     * @param ignore If <code>true</code>, if an exception happens during
+     * rendering, of if the attribute is null, the problem will be ignored.
+     * @param request The request.
+     * @throws IOException If an I/O error happens during rendering.
+     */
+    private void renderAttribute(Attribute attribute, TilesContainer container,
+            Writer writer, boolean ignore, Request request)
+            throws IOException {
+        try {
+            if (attribute == null && ignore) {
+                return;
+            }
+            Object value = container.evaluate(attribute, request);
+            if(value != null) {
+            	writer.write(value.toString());
+            }
+        } catch (IOException e) {
+            if (!ignore) {
+                throw e;
+            } else if (log.isDebugEnabled()) {
+                log.debug("Ignoring exception", e);
+            }
+        } catch (RuntimeException e) {
+            if (!ignore) {
+                throw e;
+            } else if (log.isDebugEnabled()) {
+                log.debug("Ignoring exception", e);
+            }
+        } finally {
+            container.endContext(request);
+        }
+    }
+}
diff --git a/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/ImportAttributeModel.java b/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/ImportAttributeModel.java
new file mode 100644
index 000000000..eec640509
--- /dev/null
+++ b/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/ImportAttributeModel.java
@@ -0,0 +1,197 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.template;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.AttributeContext;
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.access.TilesAccess;
+import org.apache.tiles.request.Request;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * <p>
+ * <strong>Import attribute(s) in specified context.</strong>
+ * </p>
+ * <p>
+ * Import attribute(s) to requested scope. Attribute name and scope are
+ * optional. If not specified, all attributes are imported in page scope. Once
+ * imported, an attribute can be used as any other beans from jsp contexts.
+ * </p>
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public class ImportAttributeModel {
+
+    /**
+     * The logging object.
+     */
+    private Logger log = LoggerFactory.getLogger(getClass());
+
+    /**
+     * Executes the model.
+     *
+     * @param name The name of the attribute to import. If it is
+     * <code>null</code>, all the attributes will be imported.
+     * @param scope The scope into which the attribute(s) will be imported. If
+     * <code>null</code>, the import will go in page scope.
+     * @param toName The name of the attribute into which the attribute will be
+     * imported. To be used in conjunction to <code>name</code>. If
+     * <code>null</code>, the value of <code>name</code> will be used.
+     * @param ignore If <code>true</code>, if the attribute is not present, the
+     * problem will be ignored.
+     * @param request The request.
+     */
+    public void execute(String name, String scope, String toName, boolean ignore, Request request) {
+        Map<String, Object> attributes = getImportedAttributes(
+                name, toName, ignore, request);
+        if (scope == null) {
+            scope = request.getAvailableScopes().get(0);
+        }
+        request.getContext(scope).putAll(attributes);
+    }
+
+    /**
+     * Retuns a Map that contains the attributes to be imported. The importing
+     * code must be done by the caller.
+     * @param name The attribute to import. If null, all the attributes will be
+     * imported.
+     * @param toName The destination name of the attribute to import. Valid only
+     * if <code>name</code> is specified.
+     * @param ignore If <code>true</code> and the attribute is not found, or an
+     * exception happens, the problem will be ignored.
+     * @param request The request.
+     *
+     * @return A Map of the attributes to be imported: the key is the name of an
+     * attribute, the value is the value of that attribute.
+     * @since 2.2.0
+     */
+    private Map<String, Object> getImportedAttributes(String name,
+            String toName, boolean ignore, Request request) {
+        TilesContainer container = TilesAccess.getCurrentContainer(request);
+        Map<String, Object> retValue = new HashMap<String, Object>();
+        AttributeContext attributeContext = container
+                .getAttributeContext(request);
+        // Some tags allow for unspecified attributes. This
+        // implies that the tag should use all of the attributes.
+        if (name != null) {
+            importSingleAttribute(container, attributeContext, name, toName,
+                    ignore, retValue, request);
+        } else {
+            importAttributes(attributeContext.getCascadedAttributeNames(),
+                    container, attributeContext, retValue, ignore, request);
+            importAttributes(attributeContext.getLocalAttributeNames(),
+                    container, attributeContext, retValue, ignore, request);
+        }
+        return retValue;
+    }
+
+    /**
+     * Imports a single attribute.
+     *
+     * @param container The Tiles container to use.
+     * @param attributeContext The context from which the attributes will be
+     * got.
+     * @param name The name of the attribute.
+     * @param toName The name of the destination attribute. If null,
+     * <code>name</code> will be used.
+     * @param ignore If <code>true</code> and the attribute is not found, or an
+     * exception happens, the problem will be ignored.
+     * @param attributes The map of the attributes to fill.
+     * @param request The request.
+     */
+    private void importSingleAttribute(TilesContainer container,
+            AttributeContext attributeContext, String name, String toName,
+            boolean ignore, Map<String, Object> attributes,
+            Request request) {
+        Attribute attr = attributeContext.getAttribute(name);
+        if (attr != null) {
+            try {
+                Object attributeValue = container.evaluate(attr,
+                        request);
+                if (attributeValue == null) {
+                    if (!ignore) {
+                        throw new NoSuchAttributeException(
+                                "Error importing attributes. " + "Attribute '"
+                                        + name + "' has a null value ");
+                    }
+                } else {
+                    if (toName != null) {
+                        attributes.put(toName, attributeValue);
+                    } else {
+                        attributes.put(name, attributeValue);
+                    }
+                }
+            } catch (RuntimeException e) {
+                if (!ignore) {
+                    throw e;
+                } else if (log.isDebugEnabled()) {
+                    log.debug("Ignoring Tiles Exception", e);
+                }
+            }
+        } else if (!ignore) {
+            throw new NoSuchAttributeException(
+                    "Error importing attributes. " + "Attribute '" + name
+                            + "' is null");
+        }
+    }
+
+    /**
+     * Imports all the attributes.
+     *
+     * @param names The names of the attributes to be imported.
+     * @param container The Tiles container to use.
+     * @param attributeContext The context from which the attributes will be
+     * got.
+     * @param attributes The map of the attributes to fill.
+     * @param ignore If <code>true</code> and the attribute is not found, or an
+     * exception happens, the problem will be ignored.
+     * @param request The request.
+     */
+    private void importAttributes(Collection<String> names,
+            TilesContainer container, AttributeContext attributeContext,
+            Map<String, Object> attributes, boolean ignore,
+            Request request) {
+        if (names == null || names.isEmpty()) {
+            return;
+        }
+
+        for (String name : names) {
+            if (name == null && !ignore) {
+                throw new NoSuchAttributeException(
+                        "Error importing attributes. "
+                                + "Attribute with null key found.");
+            } else if (name == null) {
+                continue;
+            }
+
+            importSingleAttribute(container, attributeContext, name, name,
+                    ignore, attributes, request);
+        }
+    }
+}
diff --git a/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/InsertAttributeModel.java b/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/InsertAttributeModel.java
new file mode 100644
index 000000000..708e81a3b
--- /dev/null
+++ b/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/InsertAttributeModel.java
@@ -0,0 +1,205 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.template;
+
+import java.io.IOException;
+import java.util.Deque;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.access.TilesAccess;
+import org.apache.tiles.autotag.core.runtime.ModelBody;
+import org.apache.tiles.request.Request;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * <p>
+ * <strong>Inserts the value of an attribute into the page.</strong>
+ * </p>
+ * <p>
+ * This tag can be flexibly used to insert the value of an attribute into a
+ * page. As in other usages in Tiles, every attribute can be determined to have
+ * a "type", either set explicitly when it was defined, or "computed". If the
+ * type is not explicit, then if the attribute value is a valid definition, it
+ * will be inserted as such. Otherwise, if it begins with a "/" character, it
+ * will be treated as a "template". Finally, if it has not otherwise been
+ * assigned a type, it will be treated as a String and included without any
+ * special handling.
+ * </p>
+ *
+ * <p>
+ * <strong>Example : </strong>
+ * </p>
+ *
+ * <pre>
+ * &lt;code&gt;
+ *           &lt;tiles:insertAttribute name=&quot;body&quot; /&gt;
+ *         &lt;/code&gt;
+ * </pre>
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public class InsertAttributeModel {
+
+    /**
+     * The logging object.
+     */
+    private Logger log = LoggerFactory.getLogger(getClass());
+
+    /**
+     * The attribute resolver to use.
+     */
+    private AttributeResolver attributeResolver;
+
+    /**
+     * Constructor that uses the defaut attribute resolver.
+     *
+     * @since 3.0.0
+     */
+    public InsertAttributeModel() {
+        this(new DefaultAttributeResolver());
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param attributeResolver The attribute resolver to use.
+     * @since 2.2.0
+     */
+    public InsertAttributeModel(AttributeResolver attributeResolver) {
+        this.attributeResolver = attributeResolver;
+    }
+
+    /**
+     * Executes the operation.
+     * @param ignore If <code>true</code>, if an exception happens during
+     * rendering, of if the attribute is null, the problem will be ignored.
+     * @param preparer The preparer to invoke before rendering the attribute.
+     * @param role A comma-separated list of roles. If present, the attribute
+     * will be rendered only if the current user belongs to one of the roles.
+     * @param defaultValue The default value of the attribute. To use only if
+     * the attribute was not computed.
+     * @param defaultValueRole The default comma-separated list of roles. To use
+     * only if the attribute was not computed.
+     * @param defaultValueType The default type of the attribute. To use only if
+     * the attribute was not computed.
+     * @param name The name of the attribute.
+     * @param value The attribute to use immediately, if not null.
+     * @param flush If <code>true</code>, the response will be flushed after the insert.
+     * @param request The request.
+     * @param modelBody The body.
+     * @throws IOException If an I/O error happens during rendering.
+     * @since 2.2.0
+     */
+    public void execute(boolean ignore, String preparer,
+            String role, Object defaultValue, String defaultValueRole,
+            String defaultValueType, String name, Attribute value,
+            boolean flush, Request request, ModelBody modelBody) throws IOException {
+        TilesContainer container = TilesAccess.getCurrentContainer(request);
+        Deque<Object> composeStack = ComposeStackUtil.getComposeStack(request);
+        Attribute attribute = resolveAttribute(container, ignore, preparer,
+                role, defaultValue, defaultValueRole, defaultValueType, name,
+                value, request);
+        if (attribute != null) {
+            composeStack.push(attribute);
+        }
+        modelBody.evaluateWithoutWriting();
+        container = TilesAccess.getCurrentContainer(request);
+        if (attribute != null) {
+            attribute = (Attribute) composeStack.pop();
+        }
+        renderAttribute(container, ignore, attribute, request);
+        if (flush) {
+            request.getWriter().flush();
+        }
+    }
+
+    /**
+     * Resolves the attribute. and starts the context.
+     *
+     * @param container The Tiles container to use.
+     * @param ignore If <code>true</code>, if an exception happens during
+     * rendering, of if the attribute is null, the problem will be ignored.
+     * @param preparer The preparer to invoke before rendering the attribute.
+     * @param role A comma-separated list of roles. If present, the attribute
+     * will be rendered only if the current user belongs to one of the roles.
+     * @param defaultValue The default value of the attribute. To use only if
+     * the attribute was not computed.
+     * @param defaultValueRole The default comma-separated list of roles. To use
+     * only if the attribute was not computed.
+     * @param defaultValueType The default type of the attribute. To use only if
+     * the attribute was not computed.
+     * @param name The name of the attribute.
+     * @param value The attribute to use immediately, if not null.
+     * @param request The request.
+     * @return The resolved attribute.
+     */
+    private Attribute resolveAttribute(TilesContainer container,
+            boolean ignore, String preparer, String role, Object defaultValue,
+            String defaultValueRole, String defaultValueType, String name,
+            Attribute value, Request request) {
+        if (preparer != null) {
+            container.prepare(preparer, request);
+        }
+        Attribute attribute = attributeResolver.computeAttribute(container,
+                value, name, role, ignore, defaultValue, defaultValueRole,
+                defaultValueType, request);
+        container.startContext(request);
+        return attribute;
+    }
+
+    /**
+     * Renders the attribute as a string.
+     * @param container The Tiles container to use.
+     * @param ignore If <code>true</code>, if an exception happens during
+     * rendering, of if the attribute is null, the problem will be ignored.
+     * @param attribute The attribute to use, previously resolved.
+     * @param request The request.
+     *
+     * @throws IOException If an I/O error happens during rendering.
+     */
+    private void renderAttribute(TilesContainer container, boolean ignore,
+            Attribute attribute, Request request) throws IOException {
+        try {
+            if (attribute == null && ignore) {
+                return;
+            }
+            container.render(attribute, request);
+        } catch (IOException e) {
+            if (!ignore) {
+                throw e;
+            } else if (log.isDebugEnabled()) {
+                log.debug("Ignoring exception", e);
+            }
+        } catch (RuntimeException e) {
+            if (!ignore) {
+                throw e;
+            } else if (log.isDebugEnabled()) {
+                log.debug("Ignoring exception", e);
+            }
+        } finally {
+            container.endContext(request);
+        }
+    }
+}
diff --git a/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/InsertDefinitionModel.java b/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/InsertDefinitionModel.java
new file mode 100644
index 000000000..1797b1500
--- /dev/null
+++ b/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/InsertDefinitionModel.java
@@ -0,0 +1,140 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.template;
+
+import java.io.IOException;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.AttributeContext;
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.access.TilesAccess;
+import org.apache.tiles.autotag.core.runtime.ModelBody;
+import org.apache.tiles.autotag.core.runtime.annotation.Parameter;
+import org.apache.tiles.request.Request;
+
+/**
+ * <p>
+ * <strong>Insert a definition.</strong>
+ * </p>
+ * <p>
+ * Insert a definition with the possibility to override and specify parameters
+ * (called attributes). A definition can be seen as a (partially or totally)
+ * filled template that can override or complete attribute values.
+ * <code>&lt;tiles:insertDefinition&gt;</code> allows to define these attributes
+ * and pass them to the inserted jsp page, called template. Attributes are
+ * defined using nested tag <code>&lt;tiles:putAttribute&gt;</code> or
+ * <code>&lt;tiles:putListAttribute&gt;</code>.
+ * </p>
+ * <p>
+ * You must specify <code>name</code> tag attribute, for inserting a definition
+ * from definitions factory.
+ * </p>
+ * <p>
+ * <strong>Example : </strong>
+ * </p>
+ *
+ * <pre>
+ * &lt;code&gt;
+ *           &lt;tiles:insertDefinition name=&quot;.my.tiles.defininition flush=&quot;true&quot;&gt;
+ *              &lt;tiles:putAttribute name=&quot;title&quot; value=&quot;My first page&quot; /&gt;
+ *              &lt;tiles:putAttribute name=&quot;header&quot; value=&quot;/common/header.jsp&quot; /&gt;
+ *              &lt;tiles:putAttribute name=&quot;footer&quot; value=&quot;/common/footer.jsp&quot; /&gt;
+ *              &lt;tiles:putAttribute name=&quot;menu&quot; value=&quot;/basic/menu.jsp&quot; /&gt;
+ *              &lt;tiles:putAttribute name=&quot;body&quot; value=&quot;/basic/helloBody.jsp&quot; /&gt;
+ *           &lt;/tiles:insertDefinition&gt;
+ *         &lt;/code&gt;
+ * </pre>
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public class InsertDefinitionModel {
+
+    /**
+     * Executes the operation.
+     * @param definitionName The name of the definition to render.
+     * @param template If specified, this template will be used instead of the
+     * one used by the definition.
+     * @param templateType The type of the template attribute.
+     * @param templateExpression The expression to evaluate to get the value of the template.
+     * @param role A comma-separated list of roles. If present, the definition
+     * will be rendered only if the current user belongs to one of the roles.
+     * @param preparer The preparer to use to invoke before the definition is
+     * rendered. If specified, it overrides the preparer specified in the
+     * definition itself.
+     * @param flush If <code>true</code>, the response will be flushed after the insert.
+     * @param request The request.
+     * @param modelBody The body.
+     * @throws IOException If something goes wrong.
+     * @since 2.2.0
+     */
+    public void execute(
+            @Parameter(name = "name", required = true) String definitionName,
+            String template, String templateType, String templateExpression,
+            String role, String preparer, boolean flush, Request request, ModelBody modelBody)
+            throws IOException {
+        TilesContainer container = TilesAccess.getCurrentContainer(request);
+        container.startContext(request);
+        modelBody.evaluateWithoutWriting();
+        container = TilesAccess.getCurrentContainer(request);
+        renderDefinition(container, definitionName, template, templateType,
+                templateExpression, role, preparer, flush, request);
+    }
+
+    /**
+     * Renders a definition.
+     *
+     * @param container The container to use.
+     * @param definitionName The name of the definition to render.
+     * @param template If specified, this template will be used instead of the
+     * one used by the definition.
+     * @param templateType The type of the template attribute.
+     * @param templateExpression The expression to evaluate to get the value of the template.
+     * @param role A comma-separated list of roles. If present, the definition
+     * will be rendered only if the current user belongs to one of the roles.
+     * @param preparer The preparer to use to invoke before the definition is
+     * rendered. If specified, it overrides the preparer specified in the
+     * definition itself.
+     * @param flush If <code>true</code>, the response will be flushed after the insert.
+     * @param request The request.
+     * @throws IOException If something goes wrong.
+     */
+    private void renderDefinition(TilesContainer container,
+            String definitionName, String template, String templateType,
+            String templateExpression, String role, String preparer,
+            boolean flush, Request request) throws IOException {
+        try {
+            AttributeContext attributeContext = container
+                    .getAttributeContext(request);
+            Attribute templateAttribute = Attribute.createTemplateAttribute(template,
+                    templateExpression, templateType, role);
+            attributeContext.setPreparer(preparer);
+            attributeContext.setTemplateAttribute(templateAttribute);
+            container.render(definitionName, request);
+            if (flush) {
+                request.getWriter().flush();
+            }
+        } finally {
+            container.endContext(request);
+        }
+    }
+}
diff --git a/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/InsertTemplateModel.java b/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/InsertTemplateModel.java
new file mode 100644
index 000000000..b17ed6827
--- /dev/null
+++ b/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/InsertTemplateModel.java
@@ -0,0 +1,134 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.template;
+
+import java.io.IOException;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.AttributeContext;
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.access.TilesAccess;
+import org.apache.tiles.autotag.core.runtime.ModelBody;
+import org.apache.tiles.autotag.core.runtime.annotation.Parameter;
+import org.apache.tiles.request.Request;
+
+/**
+ * <p>
+ * <strong>Insert a template.</strong>
+ * </p>
+ * <p>
+ * Insert a template with the possibility to pass parameters (called
+ * attributes). A template can be seen as a procedure that can take parameters
+ * or attributes. <code>&lt;tiles:insertTemplate&gt;</code> allows to define
+ * these attributes and pass them to the inserted jsp page, called template.
+ * Attributes are defined using nested tag
+ * <code>&lt;tiles:putAttribute&gt;</code> or
+ * <code>&lt;tiles:putListAttribute&gt;</code>.
+ * </p>
+ * <p>
+ * You must specify <code>template</code> attribute, for inserting a template
+ * </p>
+ *
+ * <p>
+ * <strong>Example : </strong>
+ * </p>
+ *
+ * <pre>
+ * &lt;code&gt;
+ *           &lt;tiles:insertTemplate template=&quot;/basic/myLayout.jsp&quot; flush=&quot;true&quot;&gt;
+ *              &lt;tiles:putAttribute name=&quot;title&quot; value=&quot;My first page&quot; /&gt;
+ *              &lt;tiles:putAttribute name=&quot;header&quot; value=&quot;/common/header.jsp&quot; /&gt;
+ *              &lt;tiles:putAttribute name=&quot;footer&quot; value=&quot;/common/footer.jsp&quot; /&gt;
+ *              &lt;tiles:putAttribute name=&quot;menu&quot; value=&quot;/basic/menu.jsp&quot; /&gt;
+ *              &lt;tiles:putAttribute name=&quot;body&quot; value=&quot;/basic/helloBody.jsp&quot; /&gt;
+ *           &lt;/tiles:insertTemplate&gt;
+ *         &lt;/code&gt;
+ * </pre>
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public class InsertTemplateModel {
+
+    /**
+     * Executes the operation.
+     * @param template The template to render.
+     * @param templateType The type of the template attribute.
+     * @param templateExpression The expression to evaluate to get the value of the template.
+     * @param role A comma-separated list of roles. If present, the template
+     * will be rendered only if the current user belongs to one of the roles.
+     * @param preparer The preparer to use to invoke before the definition is
+     * rendered. If specified, it overrides the preparer specified in the
+     * definition itself.
+     * @param flush If <code>true</code>, the response will be flushed after the insert.
+     * @param request The request.
+     * @param modelBody The body.
+     * @throws IOException If something goes wrong.
+     * @since 2.2.0
+     */
+    public void execute(@Parameter(required = true) String template,
+            String templateType, String templateExpression, String role,
+            String preparer, boolean flush, Request request, ModelBody modelBody)
+            throws IOException {
+        TilesContainer container = TilesAccess.getCurrentContainer(request);
+        container.startContext(request);
+        modelBody.evaluateWithoutWriting();
+        container = TilesAccess.getCurrentContainer(request);
+        renderTemplate(container, template, templateType, templateExpression,
+                role, preparer, flush, request);
+    }
+
+    /**
+     * Renders a template.
+     *
+     * @param container The container to use.
+     * @param template The template to render.
+     * @param templateType The type of the template attribute.
+     * @param templateExpression The expression to evaluate to get the value of the template.
+     * @param role A comma-separated list of roles. If present, the template
+     * will be rendered only if the current user belongs to one of the roles.
+     * @param preparer The preparer to use to invoke before the definition is
+     * rendered. If specified, it overrides the preparer specified in the
+     * definition itself.
+     * @param flush If <code>true</code>, the response will be flushed after the insert.
+     * @param request The request.
+     * @throws IOException If something goes wrong.
+     */
+    private void renderTemplate(TilesContainer container, String template,
+            String templateType, String templateExpression, String role,
+            String preparer, boolean flush, Request request) throws IOException {
+        try {
+            AttributeContext attributeContext = container
+                    .getAttributeContext(request);
+            Attribute templateAttribute = Attribute.createTemplateAttribute(template,
+                    templateExpression, templateType, role);
+            attributeContext.setPreparer(preparer);
+            attributeContext.setTemplateAttribute(templateAttribute);
+            container.renderContext(request);
+            if (flush) {
+                request.getWriter().flush();
+            }
+        } finally {
+            container.endContext(request);
+        }
+    }
+}
diff --git a/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/NoSuchAttributeException.java b/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/NoSuchAttributeException.java
new file mode 100644
index 000000000..b2f6e5b9c
--- /dev/null
+++ b/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/NoSuchAttributeException.java
@@ -0,0 +1,72 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.template;
+
+import org.apache.tiles.TilesException;
+
+/**
+ * Indicates that a named attribute has not been found.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public class NoSuchAttributeException extends TilesException {
+
+    /**
+     * Constructor.
+     *
+     * @since 2.2.0
+     */
+    public NoSuchAttributeException() {
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param message The detail message.
+     * @since 2.2.0
+     */
+    public NoSuchAttributeException(String message) {
+        super(message);
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param e The exception to be wrapped.
+     * @since 2.2.0
+     */
+    public NoSuchAttributeException(Exception e) {
+        super(e);
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param message The detail message.
+     * @param e The exception to be wrapped.
+     * @since 2.2.0
+     */
+    public NoSuchAttributeException(String message, Exception e) {
+        super(message, e);
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/PutAttributeModel.java b/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/PutAttributeModel.java
new file mode 100644
index 000000000..aa6551cd2
--- /dev/null
+++ b/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/PutAttributeModel.java
@@ -0,0 +1,154 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.template;
+
+import java.io.IOException;
+import java.util.Deque;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.AttributeContext;
+import org.apache.tiles.Expression;
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.access.TilesAccess;
+import org.apache.tiles.autotag.core.runtime.ModelBody;
+import org.apache.tiles.autotag.core.runtime.annotation.Parameter;
+import org.apache.tiles.request.Request;
+
+/**
+ * <p>
+ * <strong>Put an attribute in enclosing attribute container tag.</strong>
+ * </p>
+ * <p>
+ * Enclosing attribute container tag can be :
+ * <ul>
+ * <li>&lt;initContainer&gt;</li>
+ * <li>&lt;definition&gt;</li>
+ * <li>&lt;insertAttribute&gt;</li>
+ * <li>&lt;insertDefinition&gt;</li>
+ * <li>&lt;putListAttribute&gt;</li>
+ * </ul>
+ * (or any other tag which implements the <code>PutAttributeTagParent</code>
+ * interface. Exception is thrown if no appropriate tag can be found.
+ * </p>
+ * <p>
+ * Put tag can have following atributes :
+ * <ul>
+ * <li>name : Name of the attribute</li>
+ * <li>value : value to put as attribute</li>
+ * <li>type : value type. Possible type are : string (value is used as direct
+ * string), template (value is used as a page url to insert), definition (value
+ * is used as a definition name to insert), object (value is used as it is)</li>
+ * <li>role : Role to check when 'insertAttribute' will be called.</li>
+ * </ul>
+ * </p>
+ * <p>
+ * Value can also come from tag body. Tag body is taken into account only if
+ * value is not set by one of the tag attributes. In this case Attribute type is
+ * "string", unless tag body define another type.
+ * </p>
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public class PutAttributeModel {
+
+    /**
+     * Executes the operation.
+     * @param name The name of the attribute to put.
+     * @param value The value of the attribute. Use this parameter, or
+     * expression, or body.
+     * @param expression The expression to calculate the value from. Use this
+     * parameter, or value, or body.
+     * @param role A comma-separated list of roles. If present, the attribute
+     * will be rendered only if the current user belongs to one of the roles.
+     * @param type The type (renderer) of the attribute.
+     * @param cascade If <code>true</code> the attribute will be cascaded to all nested attributes.
+     * @param request The request.
+     * @param modelBody The body.
+     * @throws IOException If the body cannot be evaluated.
+     * @since 2.2.0
+     */
+    public void execute(@Parameter(required = true) String name, Object value,
+            String expression, String role, String type, boolean cascade,
+            Request request, ModelBody modelBody) throws IOException {
+        Deque<Object> composeStack = ComposeStackUtil.getComposeStack(request);
+        Attribute attribute = new Attribute();
+        composeStack.push(attribute);
+        String currentBody = modelBody.evaluateAsString();
+        TilesContainer container = TilesAccess.getCurrentContainer(request);
+        attribute = (Attribute) composeStack.pop();
+        putAttributeInParent(attribute, container, composeStack, name,
+                value, expression, currentBody, role, type, cascade, request);
+    }
+
+    /**
+     * Determines the parent and puts the attribute inside it.
+     *
+     * @param attribute The attribute to put;
+     * @param container The Tiles container to use.
+     * @param composeStack The composing stack.
+     * @param name The name of the attribute to put.
+     * @param value The value of the attribute. Use this parameter, or
+     * expression, or body.
+     * @param expression The expression to calculate the value from. Use this
+     * parameter, or value, or body.
+     * @param body The body of the tag. Use this parameter, or value, or
+     * expression.
+     * @param role A comma-separated list of roles. If present, the attribute
+     * will be rendered only if the current user belongs to one of the roles.
+     * @param type The type (renderer) of the attribute.
+     * @param cascade If <code>true</code> the attribute will be cascaded to all nested attributes.
+     * @param request The request.
+     */
+    private void putAttributeInParent(Attribute attribute,
+            TilesContainer container, Deque<Object> composeStack, String name,
+            Object value, String expression, String body, String role,
+            String type, boolean cascade, Request request) {
+        AttributeContext attributeContext = null;
+        if (!composeStack.isEmpty()) {
+            Object obj = composeStack.peek();
+            if (obj instanceof AttributeContext) {
+                attributeContext = (AttributeContext) obj;
+            }
+        }
+        if (attributeContext == null) {
+            attributeContext = container.getAttributeContext(request);
+        }
+        if (value != null) {
+            attribute.setValue(value);
+        } else if (attribute.getValue() == null && body != null) {
+            attribute.setValue(body);
+        }
+        if (expression != null) {
+            attribute.setExpressionObject(Expression
+                    .createExpressionFromDescribedExpression(expression));
+        }
+        if (role != null) {
+            attribute.setRole(role);
+        }
+        if (type != null) {
+            attribute.setRenderer(type);
+        }
+
+        attributeContext.putAttribute(name, attribute, cascade);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/PutListAttributeModel.java b/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/PutListAttributeModel.java
new file mode 100644
index 000000000..64014430b
--- /dev/null
+++ b/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/PutListAttributeModel.java
@@ -0,0 +1,87 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.template;
+
+import java.io.IOException;
+import java.util.Deque;
+
+import org.apache.tiles.AttributeContext;
+import org.apache.tiles.Definition;
+import org.apache.tiles.ListAttribute;
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.access.TilesAccess;
+import org.apache.tiles.autotag.core.runtime.ModelBody;
+import org.apache.tiles.autotag.core.runtime.annotation.Parameter;
+import org.apache.tiles.request.Request;
+
+/**
+ * <p>
+ * <strong>Declare a list that will be pass as attribute to tile. </strong>
+ * </p>
+ * <p>
+ * Declare a list that will be pass as attribute to tile. List elements are
+ * added using the tags 'addAttribute' or 'addListAttribute'. This tag can only
+ * be used inside 'insertTemplate', 'insertDefinition', 'definition' tags.
+ * </p>
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public class PutListAttributeModel {
+
+    /**
+     * Executes the model.
+     *
+     * @param name The name of the attribute to put.
+     * @param role A comma-separated list of roles. If present, the attribute
+     * will be rendered only if the current user belongs to one of the roles.
+     * @param inherit If <code>true</code>, the list attribute will use, as first elements, the
+     * list contained in the list attribute, put with the same name, of the containing definition.
+     * @param cascade If <code>true</code> the attribute will be cascaded to all nested attributes.
+     * @param request The request.
+     * @param modelBody The body.
+     * @throws IOException If the body cannot be evaluated.
+     */
+    public void execute(@Parameter(required = true) String name, String role,
+            boolean inherit, boolean cascade, Request request,
+            ModelBody modelBody) throws IOException {
+        Deque<Object> composeStack = ComposeStackUtil.getComposeStack(request);
+        ListAttribute listAttribute = new ListAttribute();
+        listAttribute.setRole(role);
+        listAttribute.setInherit(inherit);
+        composeStack.push(listAttribute);
+        modelBody.evaluateWithoutWriting();
+        TilesContainer container = TilesAccess.getCurrentContainer(request);
+        listAttribute = (ListAttribute) composeStack.pop();
+        AttributeContext attributeContext = null;
+        if (!composeStack.isEmpty()) {
+            Object obj = composeStack.peek();
+            if (obj instanceof Definition) {
+                attributeContext = (AttributeContext) obj;
+            }
+        }
+        if (attributeContext == null) {
+            attributeContext = container.getAttributeContext(request);
+        }
+        attributeContext.putAttribute(name, listAttribute, cascade);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/SetCurrentContainerModel.java b/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/SetCurrentContainerModel.java
new file mode 100644
index 000000000..5f7b014f4
--- /dev/null
+++ b/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/SetCurrentContainerModel.java
@@ -0,0 +1,44 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.template;
+
+import org.apache.tiles.access.TilesAccess;
+import org.apache.tiles.request.Request;
+
+/**
+ * Selects a container to be used as the "current" container.
+ *
+ * @version $Rev$ $Date$
+ * @since 3.0.0
+ */
+public class SetCurrentContainerModel {
+
+    /**
+     * Executes the model.
+     *
+     * @param containerKey The key of the container to be used as "current". If
+     * <code>null</code>, the default one will be used.
+     * @param request The request.
+     */
+    public void execute(String containerKey, Request request) {
+        TilesAccess.setCurrentContainer(request, containerKey);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/package-info.java b/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/package-info.java
new file mode 100644
index 000000000..828b7ac3d
--- /dev/null
+++ b/Java-base/tiles/src/tiles-template/src/main/java/org/apache/tiles/template/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * $Id: package-info.java 1049711 2010-12-15 21:12:00Z apetrelli $
+ *
+ * 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.
+ */
+/**
+ * Tiles template classes, that enable to write support code for template languages (JSP, FreeMarker, Velocity).
+ */
+package org.apache.tiles.template;
diff --git a/Java-base/tiles/src/tiles-template/src/site/site.xml b/Java-base/tiles/src/tiles-template/src/site/site.xml
new file mode 100644
index 000000000..b4d2510aa
--- /dev/null
+++ b/Java-base/tiles/src/tiles-template/src/site/site.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<project name="Apache Tiles - Template Technologies Support">
+     <skin>
+        <groupId>org.apache.maven.skins</groupId>
+        <artifactId>maven-fluido-skin</artifactId>
+        <version>1.3.0</version>
+     </skin>
+     <custom>
+        <fluidoSkin>
+        <topBarEnabled>true</topBarEnabled>
+        <sideBarEnabled>false</sideBarEnabled>
+        <searchEnabled>true</searchEnabled>
+        <gitHub>
+            <projectId>apache/tiles</projectId>
+            <ribbonOrientation>right</ribbonOrientation>
+            <ribbonColor>darkblue</ribbonColor>
+        </gitHub>
+        </fluidoSkin>
+     </custom>
+    <bannerLeft>
+        <name>Apache Tiles&#8482;</name>
+        <src>http://tiles.apache.org/images/logo.png</src>
+        <href>http://tiles.apache.org</href>
+    </bannerLeft>
+    <bannerRight>
+        <name>Apache Software Foundation</name>
+        <src>http://struts.apache.org/images/asf-logo.gif</src>
+        <href>http://www.apache.org</href>
+    </bannerRight>
+    <body>
+
+        <menu name="Apache Tiles&#8482;">
+            <item
+                   name="Welcome"
+                   href="../../index.html"/>
+            <item
+                    name="Tiles 3.0.x"
+                    href="../../framework/index.html"/>
+            <item
+                    name="Autotag 1.0.x"
+                    href="../../tiles-autotag/index.html"/>
+            <item
+                    name="Request 1.0.x"
+                    href="../../tiles-request/index.html"/>
+            <item
+                   name="Security bulletins"
+                   href="../security/index.html"/>
+            <item
+                   name="Download"
+                   href="http://tiles.apache.org/download.html"/>
+        </menu>
+
+        <menu ref="modules" />
+        <menu ref="reports" />
+
+        <footer>
+            <div class="row span12">
+                Apache Tiles, Tiles, Apache, the Apache feather logo, and the Apache Tiles
+                project logos are trademarks of The Apache Software Foundation.
+            </div>
+        </footer>
+    </body>
+</project>
diff --git a/Java-base/tiles/src/tiles-template/src/test/java/org/apache/tiles/template/AddAttributeModelTest.java b/Java-base/tiles/src/tiles-template/src/test/java/org/apache/tiles/template/AddAttributeModelTest.java
new file mode 100644
index 000000000..17c9006ad
--- /dev/null
+++ b/Java-base/tiles/src/tiles-template/src/test/java/org/apache/tiles/template/AddAttributeModelTest.java
@@ -0,0 +1,111 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.template;
+
+import static org.easymock.EasyMock.*;
+import static org.easymock.classextension.EasyMock.*;
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.util.ArrayDeque;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.ListAttribute;
+import org.apache.tiles.autotag.core.runtime.ModelBody;
+import org.apache.tiles.request.Request;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests {@link AddAttributeModel}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class AddAttributeModelTest {
+
+    /**
+     * The model to test.
+     */
+    private AddAttributeModel model;
+
+    /** Sets up the test. */
+    @Before
+    public void setUp() {
+        model = new AddAttributeModel();
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.template.AddAttributeModel
+     * #execute(java.lang.Object, java.lang.String, java.lang.String, java.lang.String,
+     * Request, ModelBody)}.
+     * @throws IOException If something goes wrong.
+     */
+    @Test
+    public void testExecute() throws IOException {
+        Request request = createMock(Request.class);
+        ModelBody modelBody = createMock(ModelBody.class);
+        Deque<Object> composeStack = new ArrayDeque<Object>();
+        ListAttribute listAttribute = new ListAttribute();
+        Attribute attribute;
+        composeStack.push(listAttribute);
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+        requestScope.put(ComposeStackUtil.COMPOSE_STACK_ATTRIBUTE_NAME, composeStack);
+
+        expect(request.getContext("request")).andReturn(requestScope).times(2);
+        expect(modelBody.evaluateAsString()).andReturn(null);
+        expect(modelBody.evaluateAsString()).andReturn("myBody");
+
+        replay(request, modelBody);
+        model.execute("myValue", "myExpression", "myRole", "myType",
+                request, modelBody);
+        List<Attribute> attributes = listAttribute.getValue();
+        assertEquals(1, attributes.size());
+        attribute = attributes.iterator().next();
+        assertEquals("myValue", attribute.getValue());
+        assertEquals("myExpression", attribute.getExpressionObject().getExpression());
+        assertEquals("myRole", attribute.getRole());
+        assertEquals("myType", attribute.getRenderer());
+
+        composeStack.clear();
+        listAttribute = new ListAttribute();
+        attribute = new Attribute();
+        composeStack.push(listAttribute);
+        composeStack.push(attribute);
+
+        model.execute(null, "myExpression", "myRole", "myType", request,
+                modelBody);
+        attributes = listAttribute.getValue();
+        assertEquals(1, attributes.size());
+        attribute = attributes.iterator().next();
+        assertEquals("myBody", attribute.getValue());
+        assertEquals("myExpression", attribute.getExpressionObject()
+                .getExpression());
+        assertEquals("myRole", attribute.getRole());
+        assertEquals("myType", attribute.getRenderer());
+        verify(request, modelBody);
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-template/src/test/java/org/apache/tiles/template/AddListAttributeModelTest.java b/Java-base/tiles/src/tiles-template/src/test/java/org/apache/tiles/template/AddListAttributeModelTest.java
new file mode 100644
index 000000000..a60e89ec3
--- /dev/null
+++ b/Java-base/tiles/src/tiles-template/src/test/java/org/apache/tiles/template/AddListAttributeModelTest.java
@@ -0,0 +1,88 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.template;
+
+import static org.easymock.EasyMock.*;
+import static org.easymock.classextension.EasyMock.*;
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.util.ArrayDeque;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tiles.ListAttribute;
+import org.apache.tiles.autotag.core.runtime.ModelBody;
+import org.apache.tiles.request.Request;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests {@link AddListAttributeModel}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class AddListAttributeModelTest {
+
+    /**
+     * The model to test.
+     */
+    private AddListAttributeModel model;
+
+    /**
+     * Sets up the test.
+     */
+    @Before
+    public void setUp() {
+        model = new AddListAttributeModel();
+    }
+
+    /**
+     * Test method for
+     * {@link AddListAttributeModel#execute(String, Request, ModelBody)}
+     * .
+     * @throws IOException If something goes wrong.
+     */
+    @Test
+    public void testExecute() throws IOException {
+        Deque<Object> composeStack = new ArrayDeque<Object>();
+        Request request = createMock(Request.class);
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+        ModelBody modelBody = createMock(ModelBody.class);
+
+        modelBody.evaluateWithoutWriting();
+        requestScope.put(ComposeStackUtil.COMPOSE_STACK_ATTRIBUTE_NAME, composeStack);
+        expect(request.getContext("request")).andReturn(requestScope);
+
+        replay(request, modelBody);
+        ListAttribute parent = new ListAttribute();
+        composeStack.push(parent);
+        model.execute("myRole", request, modelBody);
+        assertEquals(1, composeStack.size());
+        assertEquals(parent, composeStack.pop());
+        assertEquals(1, parent.getValue().size());
+        ListAttribute listAttribute = (ListAttribute) parent.getValue().get(0);
+        assertEquals("myRole", listAttribute.getRole());
+        verify(request, modelBody);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-template/src/test/java/org/apache/tiles/template/ComposeStackUtilTest.java b/Java-base/tiles/src/tiles-template/src/test/java/org/apache/tiles/template/ComposeStackUtilTest.java
new file mode 100644
index 000000000..d857adc75
--- /dev/null
+++ b/Java-base/tiles/src/tiles-template/src/test/java/org/apache/tiles/template/ComposeStackUtilTest.java
@@ -0,0 +1,125 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.template;
+
+import static org.easymock.EasyMock.*;
+import static org.junit.Assert.*;
+
+import java.util.ArrayDeque;
+import java.util.Date;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tiles.request.Request;
+import org.apache.tiles.template.ComposeStackUtil;
+import org.junit.Test;
+
+/**
+ * Tests {@link ComposeStackUtil}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ComposeStackUtilTest {
+
+    /**
+     * An integer value.
+     */
+    private static final int INT_VALUE = 3;
+
+    /**
+     * A long value.
+     */
+    private static final long LONG_VALUE = 2L;
+
+    /**
+     * Test method for {@link org.apache.tiles.template.ComposeStackUtil
+     * #findAncestorWithClass(java.util.Stack, java.lang.Class)}.
+     */
+    @Test
+    public void testFindAncestorWithClass() {
+        Deque<Object> composeStack = new ArrayDeque<Object>();
+        Integer integerValue = new Integer(1);
+        Long longValue = new Long(LONG_VALUE);
+        String stringValue = "my value";
+        Integer integerValue2 = new Integer(INT_VALUE);
+        composeStack.push(integerValue);
+        composeStack.push(longValue);
+        composeStack.push(stringValue);
+        composeStack.push(integerValue2);
+        assertEquals(integerValue2, ComposeStackUtil.findAncestorWithClass(composeStack, Integer.class));
+        assertEquals(longValue, ComposeStackUtil.findAncestorWithClass(composeStack, Long.class));
+        assertEquals(stringValue, ComposeStackUtil.findAncestorWithClass(composeStack, String.class));
+        assertEquals(integerValue2, ComposeStackUtil.findAncestorWithClass(composeStack, Object.class));
+        assertNull(ComposeStackUtil.findAncestorWithClass(composeStack, Date.class));
+    }
+
+    /**
+     * Tests {@link ComposeStackUtil#getComposeStack(org.apache.tiles.request.Request)}.
+     */
+    @Test
+    public void testGetComposeStackNull() {
+        Request request = createMock(Request.class);
+
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+        expect(request.getContext("request")).andReturn(requestScope);
+
+        replay(request);
+        assertSame(ComposeStackUtil.getComposeStack(request),
+                requestScope.get(ComposeStackUtil.COMPOSE_STACK_ATTRIBUTE_NAME));
+        verify(request);
+    }
+
+    /**
+     * Tests {@link ComposeStackUtil#getComposeStack(org.apache.tiles.request.Request)}.
+     */
+    @Test
+    public void testGetComposeStackNotNull() {
+        Request request = createMock(Request.class);
+        @SuppressWarnings("unchecked")
+        Deque<Object> composeStack = createMock(Deque.class);
+
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+        requestScope.put(ComposeStackUtil.COMPOSE_STACK_ATTRIBUTE_NAME, composeStack);
+        expect(request.getContext("request")).andReturn(requestScope);
+
+        replay(request, composeStack);
+        assertSame(composeStack, ComposeStackUtil.getComposeStack(request));
+        verify(request, composeStack);
+    }
+
+    /**
+     * Tests {@link ComposeStackUtil#getComposeStack(org.apache.tiles.request.Request)}.
+     */
+    @Test
+    public void testGetComposeStackNoNull() {
+        Request request = createMock(Request.class);
+
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+        expect(request.getContext("request")).andReturn(requestScope);
+
+        replay(request);
+        assertSame(ComposeStackUtil.getComposeStack(request),
+                requestScope.get(ComposeStackUtil.COMPOSE_STACK_ATTRIBUTE_NAME));
+        verify(request);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-template/src/test/java/org/apache/tiles/template/DefaultAttributeResolverTest.java b/Java-base/tiles/src/tiles-template/src/test/java/org/apache/tiles/template/DefaultAttributeResolverTest.java
new file mode 100644
index 000000000..98ac3fed4
--- /dev/null
+++ b/Java-base/tiles/src/tiles-template/src/test/java/org/apache/tiles/template/DefaultAttributeResolverTest.java
@@ -0,0 +1,163 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.template;
+
+import static org.junit.Assert.*;
+import static org.easymock.EasyMock.*;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.AttributeContext;
+import org.apache.tiles.Expression;
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.request.Request;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests {@link DefaultAttributeResolver}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class DefaultAttributeResolverTest {
+
+    /**
+     * The resolver to test.
+     */
+    private DefaultAttributeResolver resolver;
+
+    /**
+     * Sets up the test.
+     */
+    @Before
+    public void setUp() {
+        resolver = new DefaultAttributeResolver();
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.template.DefaultAttributeResolver
+     * #computeAttribute(org.apache.tiles.TilesContainer, org.apache.tiles.Attribute,
+     * java.lang.String, java.lang.String, boolean, java.lang.Object, java.lang.String,
+     * java.lang.String, Request)}.
+     */
+    @Test
+    public void testComputeAttributeInContext() {
+        TilesContainer container = createMock(TilesContainer.class);
+        AttributeContext attributeContext = createMock(AttributeContext.class);
+        Request request = createMock(Request.class);
+        Attribute attribute = new Attribute("myValue", Expression
+                .createExpression("myExpression", null), "myRole", "myRenderer");
+
+        expect(container.getAttributeContext(request)).andReturn(attributeContext);
+        expect(attributeContext.getAttribute("myName")).andReturn(attribute);
+
+        replay(container, attributeContext, request);
+        assertEquals(attribute, resolver.computeAttribute(container, null,
+                "myName", null, false, null, null, null, request));
+        verify(container, attributeContext, request);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.template.DefaultAttributeResolver
+     * #computeAttribute(org.apache.tiles.TilesContainer, org.apache.tiles.Attribute,
+     * java.lang.String, java.lang.String, boolean, java.lang.Object, java.lang.String,
+     * java.lang.String, Request)}.
+     */
+    @Test
+    public void testComputeAttributeInCall() {
+        TilesContainer container = createMock(TilesContainer.class);
+        Request request = createMock(Request.class);
+        Attribute attribute = new Attribute("myValue", Expression
+                .createExpression("myExpression", null), "myRole", "myRenderer");
+
+        replay(container, request);
+        assertEquals(attribute, resolver.computeAttribute(container, attribute,
+                null, null, false, null, null, null, request));
+        verify(container, request);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.template.DefaultAttributeResolver
+     * #computeAttribute(org.apache.tiles.TilesContainer, org.apache.tiles.Attribute,
+     * java.lang.String, java.lang.String, boolean, java.lang.Object, java.lang.String,
+     * java.lang.String, Request)}.
+     */
+    @Test
+    public void testComputeAttributeDefault() {
+        TilesContainer container = createMock(TilesContainer.class);
+        Request request = createMock(Request.class);
+        AttributeContext attributeContext = createMock(AttributeContext.class);
+
+        expect(container.getAttributeContext(request)).andReturn(attributeContext);
+        expect(attributeContext.getAttribute("myName")).andReturn(null);
+
+        replay(container, attributeContext, request);
+        Attribute attribute = resolver.computeAttribute(container, null,
+                "myName", null, false, "defaultValue", "defaultRole",
+                "defaultType", request);
+        assertEquals("defaultValue", attribute.getValue());
+        assertEquals("defaultRole", attribute.getRole());
+        assertEquals("defaultType", attribute.getRenderer());
+        verify(container, attributeContext, request);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.template.DefaultAttributeResolver
+     * #computeAttribute(org.apache.tiles.TilesContainer, org.apache.tiles.Attribute,
+     * java.lang.String, java.lang.String, boolean, java.lang.Object, java.lang.String,
+     * java.lang.String, Request)}.
+     */
+    @Test(expected = NoSuchAttributeException.class)
+    public void testComputeAttributeException() {
+        TilesContainer container = createMock(TilesContainer.class);
+        AttributeContext attributeContext = createMock(AttributeContext.class);
+        Request request = createMock(Request.class);
+
+        expect(container.getAttributeContext(request)).andReturn(attributeContext);
+        expect(attributeContext.getAttribute("myName")).andReturn(null);
+
+        replay(container, attributeContext, request);
+        resolver.computeAttribute(container, null, "myName", null, false, null,
+                "defaultRole", "defaultType", request);
+        verify(container, attributeContext, request);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.template.DefaultAttributeResolver
+     * #computeAttribute(org.apache.tiles.TilesContainer, org.apache.tiles.Attribute,
+     * java.lang.String, java.lang.String, boolean, java.lang.Object, java.lang.String,
+     * java.lang.String, Request)}.
+     */
+    @Test
+    public void testComputeAttributeIgnore() {
+        TilesContainer container = createMock(TilesContainer.class);
+        AttributeContext attributeContext = createMock(AttributeContext.class);
+        Request request = createMock(Request.class);
+
+        expect(container.getAttributeContext(request)).andReturn(attributeContext);
+        expect(attributeContext.getAttribute("myName")).andReturn(null);
+
+        replay(container, attributeContext, request);
+        assertNull(resolver.computeAttribute(container, null, "myName", null, true, null,
+                "defaultRole", "defaultType", request));
+        verify(container, attributeContext, request);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-template/src/test/java/org/apache/tiles/template/DefinitionModelTest.java b/Java-base/tiles/src/tiles-template/src/test/java/org/apache/tiles/template/DefinitionModelTest.java
new file mode 100644
index 000000000..08d73e59b
--- /dev/null
+++ b/Java-base/tiles/src/tiles-template/src/test/java/org/apache/tiles/template/DefinitionModelTest.java
@@ -0,0 +1,96 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.template;
+
+import static org.easymock.EasyMock.*;
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.util.ArrayDeque;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.Definition;
+import org.apache.tiles.access.TilesAccess;
+import org.apache.tiles.autotag.core.runtime.ModelBody;
+import org.apache.tiles.mgmt.MutableTilesContainer;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.Request;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests {@link DefinitionModel}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class DefinitionModelTest {
+
+    /**
+     * The model to test.
+     */
+    private DefinitionModel model;
+
+    /**
+     * Sets up the test.
+     */
+    @Before
+    public void setUp() {
+        model = new DefinitionModel();
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.template.DefinitionModel
+     * #execute(java.lang.String, java.lang.String,
+     * java.lang.String, java.lang.String, java.lang.String, Request, ModelBody)}.
+     * @throws IOException If something goes wrong.
+     */
+    @Test
+    public void testExecute() throws IOException {
+        MutableTilesContainer container = createMock(MutableTilesContainer.class);
+        Request request = createMock(Request.class);
+        Deque<Object> composeStack = new ArrayDeque<Object>();
+        Attribute attribute = new Attribute();
+        composeStack.push(attribute);
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+        requestScope.put(ComposeStackUtil.COMPOSE_STACK_ATTRIBUTE_NAME, composeStack);
+        requestScope.put(TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME, container);
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        ModelBody modelBody = createMock(ModelBody.class);
+
+        modelBody.evaluateWithoutWriting();
+        expect(request.getApplicationContext()).andReturn(applicationContext);
+        expect(request.getContext("request")).andReturn(requestScope).anyTimes();
+        container.register((Definition) notNull(), eq(request));
+
+        replay(container, request, modelBody, applicationContext);
+        model.execute("myName", "myTemplate", "myRole", "myExtends",
+                "myPreparer", request, modelBody);
+        assertEquals(1, composeStack.size());
+        attribute = (Attribute) composeStack.peek();
+        assertEquals("definition", attribute.getRenderer());
+        verify(container, request, modelBody, applicationContext);
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-template/src/test/java/org/apache/tiles/template/GetAsStringModelTest.java b/Java-base/tiles/src/tiles-template/src/test/java/org/apache/tiles/template/GetAsStringModelTest.java
new file mode 100644
index 000000000..cd26523ac
--- /dev/null
+++ b/Java-base/tiles/src/tiles-template/src/test/java/org/apache/tiles/template/GetAsStringModelTest.java
@@ -0,0 +1,145 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.template;
+
+import static org.easymock.EasyMock.*;
+import static org.easymock.classextension.EasyMock.*;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.ArrayDeque;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.AttributeContext;
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.access.TilesAccess;
+import org.apache.tiles.autotag.core.runtime.ModelBody;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.Request;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests {@link GetAsStringModel}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class GetAsStringModelTest {
+
+    /**
+     * The mock resolver.
+     */
+    private AttributeResolver resolver;
+
+    /**
+     * The model to test.
+     */
+    private GetAsStringModel model;
+
+    /**
+     * Sets up the test.
+     */
+    @Before
+    public void setUp() {
+        resolver = createMock(AttributeResolver.class);
+        model = new GetAsStringModel(resolver);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.template.GetAsStringModel
+     * #execute(boolean, java.lang.String, java.lang.String,
+     * java.lang.Object, java.lang.String, java.lang.String, java.lang.String,
+     * org.apache.tiles.Attribute, Request, ModelBody)}.
+     * @throws IOException If something goes wrong.
+     */
+    @Test
+    public void testExecute() throws IOException {
+        TilesContainer container = createMock(TilesContainer.class);
+        Attribute attribute = createMock(Attribute.class);
+        AttributeContext attributeContext = createMock(AttributeContext.class);
+        Request request = createMock(Request.class);
+        Writer writer = createMock(Writer.class);
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+        Deque<Object> composeStack = new ArrayDeque<Object>();
+        requestScope.put(ComposeStackUtil.COMPOSE_STACK_ATTRIBUTE_NAME, composeStack);
+        requestScope.put(TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME, container);
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        ModelBody modelBody = createMock(ModelBody.class);
+
+        modelBody.evaluateWithoutWriting();
+        expect(request.getApplicationContext()).andReturn(applicationContext).times(2);
+        expect(request.getContext("request")).andReturn(requestScope).anyTimes();
+        expect(request.getWriter()).andReturn(writer);
+        container.prepare("myPreparer", request);
+        expect(resolver.computeAttribute(container, attribute, "myName", "myRole", false, "myDefaultValue",
+                "myDefaultValueRole", "myDefaultValueType", request)).andReturn(attribute);
+        expect(container.startContext(request)).andReturn(attributeContext);
+        expect(container.evaluate(attribute, request)).andReturn("myValue");
+        writer.write("myValue");
+        container.endContext(request);
+
+        replay(resolver, container, writer, request, applicationContext, modelBody);
+        model.execute(false, "myPreparer", "myRole", "myDefaultValue", "myDefaultValueRole", "myDefaultValueType",
+                "myName", attribute, request, modelBody);
+        verify(resolver, container, writer, request, applicationContext, modelBody);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.template.GetAsStringModel
+     * #execute(boolean, java.lang.String, java.lang.String,
+     * java.lang.Object, java.lang.String, java.lang.String, java.lang.String,
+     * org.apache.tiles.Attribute, Request, ModelBody)} when ignore flag is set.
+     * @throws IOException If something goes wrong.
+     */
+    @Test
+    public void testExecuteIgnore() throws IOException {
+        TilesContainer container = createMock(TilesContainer.class);
+        AttributeContext attributeContext = createMock(AttributeContext.class);
+        Request request = createMock(Request.class);
+        Writer writer = createMock(Writer.class);
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+        Deque<Object> composeStack = new ArrayDeque<Object>();
+        requestScope.put(ComposeStackUtil.COMPOSE_STACK_ATTRIBUTE_NAME, composeStack);
+        requestScope.put(TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME, container);
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        ModelBody modelBody = createMock(ModelBody.class);
+
+        modelBody.evaluateWithoutWriting();
+        expect(request.getApplicationContext()).andReturn(applicationContext).times(2);
+        expect(request.getContext("request")).andReturn(requestScope).anyTimes();
+        expect(request.getWriter()).andReturn(writer);
+        container.prepare("myPreparer", request);
+        expect(resolver.computeAttribute(container, null, "myName", "myRole", true, "myDefaultValue",
+                "myDefaultValueRole", "myDefaultValueType", request)).andReturn(null);
+        expect(container.startContext(request)).andReturn(attributeContext);
+        container.endContext(request);
+
+        replay(resolver, container, writer, request, applicationContext, modelBody);
+        model.execute(true, "myPreparer", "myRole", "myDefaultValue", "myDefaultValueRole", "myDefaultValueType",
+                "myName", null, request, modelBody);
+        verify(resolver, container, writer, request, applicationContext, modelBody);
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-template/src/test/java/org/apache/tiles/template/ImportAttributeModelTest.java b/Java-base/tiles/src/tiles-template/src/test/java/org/apache/tiles/template/ImportAttributeModelTest.java
new file mode 100644
index 000000000..b3a0bebc0
--- /dev/null
+++ b/Java-base/tiles/src/tiles-template/src/test/java/org/apache/tiles/template/ImportAttributeModelTest.java
@@ -0,0 +1,320 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.template;
+
+import static org.junit.Assert.*;
+import static org.easymock.EasyMock.*;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.AttributeContext;
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.access.TilesAccess;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.Request;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests {@link ImportAttributeModel}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ImportAttributeModelTest {
+
+    /**
+     * The size of the attributes collection.
+     */
+    private static final int ATTRIBUTES_SIZE = 4;
+
+    /**
+     * The model to test.
+     */
+    private ImportAttributeModel model;
+
+    /**
+     * Sets up the test.
+     */
+    @Before
+    public void setUp() {
+        model = new ImportAttributeModel();
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.template.ImportAttributeModel
+     * #execute(String, String, String, boolean, Request).
+     */
+    @Test
+    public void testExecuteSingle() {
+        TilesContainer container = createMock(TilesContainer.class);
+        AttributeContext attributeContext = createMock(AttributeContext.class);
+        Attribute attribute = new Attribute();
+        Request request = createMock(Request.class);
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+        requestScope.put(TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME, container);
+
+        expect(request.getApplicationContext()).andReturn(applicationContext);
+        expect(request.getContext("request")).andReturn(requestScope).anyTimes();
+        expect(container.getAttributeContext(request)).andReturn(attributeContext);
+        expect(attributeContext.getAttribute("myName")).andReturn(attribute);
+        expect(container.evaluate(attribute, request)).andReturn("myEvaluatedValue");
+
+        replay(container, attributeContext, request, applicationContext);
+        model.execute("myName", "request", null, false, request);
+        Map<String, Object> attributes = requestScope;
+        assertEquals(2, attributes.size());
+        assertEquals("myEvaluatedValue", attributes.get("myName"));
+        verify(container, attributeContext, request, applicationContext);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.template.ImportAttributeModel
+     * #execute(String, String, String, boolean, Request).
+     */
+    @Test
+    public void testExecuteSingleToName() {
+        TilesContainer container = createMock(TilesContainer.class);
+        Request request = createMock(Request.class);
+        AttributeContext attributeContext = createMock(AttributeContext.class);
+        Attribute attribute = new Attribute();
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+        requestScope.put(TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME, container);
+
+        expect(request.getApplicationContext()).andReturn(applicationContext);
+        expect(request.getContext("request")).andReturn(requestScope).anyTimes();
+        expect(container.getAttributeContext(request)).andReturn(attributeContext);
+        expect(attributeContext.getAttribute("myName")).andReturn(attribute);
+        expect(container.evaluate(attribute, request)).andReturn("myEvaluatedValue");
+
+        replay(container, attributeContext, request, applicationContext);
+        model.execute("myName", "request", "myToName", false, request);
+        Map<String, Object> attributes = requestScope;
+        assertEquals(2, attributes.size());
+        assertEquals("myEvaluatedValue", attributes.get("myToName"));
+        verify(container, attributeContext, request, applicationContext);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.template.ImportAttributeModel
+     * #execute(String, String, String, boolean, Request).
+     */
+    @Test
+    public void testExecuteAll() {
+        TilesContainer container = createMock(TilesContainer.class);
+        Request request = createMock(Request.class);
+        AttributeContext attributeContext = createMock(AttributeContext.class);
+        Attribute attribute1 = new Attribute("myValue1");
+        Attribute attribute2 = new Attribute("myValue2");
+        Attribute attribute3 = new Attribute("myValue3");
+        Set<String> cascadedNames = new HashSet<String>();
+        cascadedNames.add("myName1");
+        cascadedNames.add("myName2");
+        Set<String> localNames = new HashSet<String>();
+        localNames.add("myName1");
+        localNames.add("myName3");
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+        requestScope.put(TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME, container);
+
+        expect(request.getApplicationContext()).andReturn(applicationContext);
+        expect(request.getContext("request")).andReturn(requestScope).anyTimes();
+        expect(container.getAttributeContext(request)).andReturn(attributeContext);
+        expect(attributeContext.getCascadedAttributeNames()).andReturn(cascadedNames);
+        expect(attributeContext.getLocalAttributeNames()).andReturn(localNames);
+        expect(attributeContext.getAttribute("myName1")).andReturn(attribute1).times(2);
+        expect(attributeContext.getAttribute("myName2")).andReturn(attribute2);
+        expect(attributeContext.getAttribute("myName3")).andReturn(attribute3);
+        expect(container.evaluate(attribute1, request)).andReturn("myEvaluatedValue1").times(2);
+        expect(container.evaluate(attribute2, request)).andReturn("myEvaluatedValue2");
+        expect(container.evaluate(attribute3, request)).andReturn("myEvaluatedValue3");
+
+        replay(container, attributeContext, request, applicationContext);
+        model.execute(null, "request", null, false, request);
+        Map<String, Object> attributes = requestScope;
+        assertEquals(ATTRIBUTES_SIZE, attributes.size());
+        assertEquals("myEvaluatedValue1", attributes.get("myName1"));
+        assertEquals("myEvaluatedValue2", attributes.get("myName2"));
+        assertEquals("myEvaluatedValue3", attributes.get("myName3"));
+        verify(container, attributeContext, request, applicationContext);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.template.ImportAttributeModel
+     * #execute(String, String, String, boolean, Request).
+     */
+    @Test(expected = NoSuchAttributeException.class)
+    public void testExecuteSingleNullAttributeException() {
+        TilesContainer container = createMock(TilesContainer.class);
+        Request request = createMock(Request.class);
+        AttributeContext attributeContext = createMock(AttributeContext.class);
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+        requestScope.put(TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME, container);
+
+        expect(request.getApplicationContext()).andReturn(applicationContext);
+        expect(request.getContext("request")).andReturn(requestScope).anyTimes();
+        expect(container.getAttributeContext(request)).andReturn(attributeContext);
+        expect(attributeContext.getAttribute("myName")).andReturn(null);
+
+        replay(container, attributeContext, request, applicationContext);
+        try {
+            model.execute("myName", "request", null, false, request);
+        } finally {
+            verify(container, attributeContext, request, applicationContext);
+        }
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.template.ImportAttributeModel
+     * #execute(String, String, String, boolean, Request).
+     */
+    @Test(expected = NoSuchAttributeException.class)
+    public void testExecuteSingleNullAttributeValueException() {
+        TilesContainer container = createMock(TilesContainer.class);
+        Request request = createMock(Request.class);
+        AttributeContext attributeContext = createMock(AttributeContext.class);
+        Attribute attribute = new Attribute();
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+        requestScope.put(TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME, container);
+
+        expect(request.getApplicationContext()).andReturn(applicationContext);
+        expect(request.getContext("request")).andReturn(requestScope).anyTimes();
+        expect(container.getAttributeContext(request)).andReturn(attributeContext);
+        expect(attributeContext.getAttribute("myName")).andReturn(attribute);
+        expect(container.evaluate(attribute, request)).andReturn(null);
+
+        replay(container, attributeContext, request, applicationContext);
+        try {
+            model.execute("myName", "request", null, false, request);
+        } finally {
+            verify(container, attributeContext, request, applicationContext);
+        }
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.template.ImportAttributeModel
+     * #execute(String, String, String, boolean, Request).
+     */
+    @Test(expected = RuntimeException.class)
+    public void testExecuteSingleRuntimeException() {
+        TilesContainer container = createMock(TilesContainer.class);
+        Request request = createMock(Request.class);
+        AttributeContext attributeContext = createMock(AttributeContext.class);
+        Attribute attribute = new Attribute();
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+        requestScope.put(TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME, container);
+
+        expect(request.getApplicationContext()).andReturn(applicationContext);
+        expect(request.getContext("request")).andReturn(requestScope).anyTimes();
+        expect(container.getAttributeContext(request)).andReturn(attributeContext);
+        expect(attributeContext.getAttribute("myName")).andReturn(attribute);
+        expect(container.evaluate(attribute, request)).andThrow(new RuntimeException());
+
+        replay(container, attributeContext, request, applicationContext);
+        try {
+            model.execute("myName", "request", null, false, request);
+        } finally {
+            verify(container, attributeContext, request, applicationContext);
+        }
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.template.ImportAttributeModel
+     * #execute(String, String, String, boolean, Request).
+     */
+    @Test
+    public void testExecuteSingleNullAttributeIgnore() {
+        TilesContainer container = createMock(TilesContainer.class);
+        Request request = createMock(Request.class);
+        AttributeContext attributeContext = createMock(AttributeContext.class);
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+        requestScope.put(TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME, container);
+
+        expect(request.getApplicationContext()).andReturn(applicationContext);
+        expect(request.getContext("request")).andReturn(requestScope).anyTimes();
+        expect(container.getAttributeContext(request)).andReturn(attributeContext);
+        expect(attributeContext.getAttribute("myName")).andReturn(null);
+
+        replay(container, attributeContext, request, applicationContext);
+        model.execute("myName", "request", null, true, request);
+        verify(container, attributeContext, request, applicationContext);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.template.ImportAttributeModel
+     * #execute(String, String, String, boolean, Request).
+     */
+    @Test
+    public void testExecuteSingleNullAttributeValueIgnore() {
+        TilesContainer container = createMock(TilesContainer.class);
+        Request request = createMock(Request.class);
+        AttributeContext attributeContext = createMock(AttributeContext.class);
+        Attribute attribute = new Attribute();
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+        requestScope.put(TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME, container);
+
+        expect(request.getApplicationContext()).andReturn(applicationContext);
+        expect(request.getContext("request")).andReturn(requestScope).anyTimes();
+        expect(container.getAttributeContext(request)).andReturn(attributeContext);
+        expect(attributeContext.getAttribute("myName")).andReturn(attribute);
+        expect(container.evaluate(attribute, request)).andReturn(null);
+
+        replay(container, attributeContext, request, applicationContext);
+        model.execute("myName", "request", null, true, request);
+        verify(container, attributeContext, request, applicationContext);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.template.ImportAttributeModel
+     * #execute(String, String, String, boolean, Request).
+     */
+    @Test
+    public void testExecuteSingleRuntimeIgnore() {
+        TilesContainer container = createMock(TilesContainer.class);
+        Request request = createMock(Request.class);
+        AttributeContext attributeContext = createMock(AttributeContext.class);
+        Attribute attribute = new Attribute();
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+        requestScope.put(TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME, container);
+
+        expect(request.getApplicationContext()).andReturn(applicationContext);
+        expect(request.getContext("request")).andReturn(requestScope).anyTimes();
+        expect(container.getAttributeContext(request)).andReturn(attributeContext);
+        expect(attributeContext.getAttribute("myName")).andReturn(attribute);
+        expect(container.evaluate(attribute, request)).andThrow(new RuntimeException());
+
+        replay(container, attributeContext, request, applicationContext);
+        model.execute("myName", "request", null, true, request);
+        verify(container, attributeContext, request, applicationContext);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-template/src/test/java/org/apache/tiles/template/InsertAttributeModelTest.java b/Java-base/tiles/src/tiles-template/src/test/java/org/apache/tiles/template/InsertAttributeModelTest.java
new file mode 100644
index 000000000..2a717f8a6
--- /dev/null
+++ b/Java-base/tiles/src/tiles-template/src/test/java/org/apache/tiles/template/InsertAttributeModelTest.java
@@ -0,0 +1,135 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.template;
+
+import static org.easymock.EasyMock.*;
+
+import java.io.IOException;
+import java.util.ArrayDeque;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.AttributeContext;
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.access.TilesAccess;
+import org.apache.tiles.autotag.core.runtime.ModelBody;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.Request;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests {@link InsertAttributeModel}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class InsertAttributeModelTest {
+
+    /**
+     * The mock resolver.
+     */
+    private AttributeResolver resolver;
+
+    /**
+     * The model to test.
+     */
+    private InsertAttributeModel model;
+
+    /**
+     * Sets up the test.
+     */
+    @Before
+    public void setUp() {
+        resolver = createMock(AttributeResolver.class);
+        model = new InsertAttributeModel(resolver);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.template.InsertAttributeModel
+     * #execute(boolean, String, String, Object, String, String, String,
+     * Attribute, boolean, Request, ModelBody)}.
+     * @throws IOException If something goes wrong.
+     */
+    @Test
+    public void testExecute() throws IOException {
+        TilesContainer container = createMock(TilesContainer.class);
+        Request request = createMock(Request.class);
+        Attribute attribute = new Attribute("myValue");
+        AttributeContext attributeContext = createMock(AttributeContext.class);
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+        requestScope.put(TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME, container);
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        ModelBody modelBody = createMock(ModelBody.class);
+
+        modelBody.evaluateWithoutWriting();
+        expect(request.getApplicationContext()).andReturn(applicationContext).times(2);
+        expect(request.getContext("request")).andReturn(requestScope).anyTimes();
+
+        container.prepare("myPreparer", request);
+        expect(resolver.computeAttribute(container, attribute, "myName", "myRole", false, "myDefaultValue",
+                "myDefaultValueRole", "myDefaultValueType", request)).andReturn(attribute);
+        expect(container.startContext(request)).andReturn(attributeContext);
+        container.endContext(request);
+        container.render(attribute, request);
+
+        replay(resolver, container, request, applicationContext, modelBody);
+        model.execute(false, "myPreparer", "myRole", "myDefaultValue", "myDefaultValueRole",
+                "myDefaultValueType", "myName", attribute, false, request, modelBody);
+        verify(resolver, container, request, applicationContext, modelBody);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.template.InsertAttributeModel
+     * #execute(boolean, String, String, Object, String, String, String,
+     * Attribute, boolean, Request, ModelBody)} when ignore flag is set.
+     * @throws IOException If something goes wrong.
+     */
+    @Test
+    public void testExecuteIgnore() throws IOException {
+        TilesContainer container = createMock(TilesContainer.class);
+        Request request = createMock(Request.class);
+        AttributeContext attributeContext = createMock(AttributeContext.class);
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+        Deque<Object> composeStack = new ArrayDeque<Object>();
+        requestScope.put(ComposeStackUtil.COMPOSE_STACK_ATTRIBUTE_NAME, composeStack);
+        requestScope.put(TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME, container);
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        ModelBody modelBody = createMock(ModelBody.class);
+
+        modelBody.evaluateWithoutWriting();
+        expect(request.getApplicationContext()).andReturn(applicationContext).times(2);
+        expect(request.getContext("request")).andReturn(requestScope).anyTimes();
+
+        container.prepare("myPreparer", request);
+        expect(resolver.computeAttribute(container, null, "myName", "myRole", true, "myDefaultValue",
+                "myDefaultValueRole", "myDefaultValueType", request)).andReturn(null);
+        expect(container.startContext(request)).andReturn(attributeContext);
+        container.endContext(request);
+
+        replay(resolver, container, request, applicationContext, modelBody);
+        model.execute(true, "myPreparer", "myRole", "myDefaultValue", "myDefaultValueRole",
+                "myDefaultValueType", "myName", null, false, request, modelBody);
+        verify(resolver, container, request, applicationContext, modelBody);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-template/src/test/java/org/apache/tiles/template/InsertDefinitionModelTest.java b/Java-base/tiles/src/tiles-template/src/test/java/org/apache/tiles/template/InsertDefinitionModelTest.java
new file mode 100644
index 000000000..692b934d2
--- /dev/null
+++ b/Java-base/tiles/src/tiles-template/src/test/java/org/apache/tiles/template/InsertDefinitionModelTest.java
@@ -0,0 +1,94 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.template;
+
+import static org.easymock.EasyMock.*;
+import static org.easymock.classextension.EasyMock.*;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.AttributeContext;
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.access.TilesAccess;
+import org.apache.tiles.autotag.core.runtime.ModelBody;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.Request;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests {@link InsertDefinitionModel}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class InsertDefinitionModelTest {
+
+    /**
+     * The model to test.
+     */
+    private InsertDefinitionModel model;
+
+    /**
+     * Sets up the test.
+     */
+    @Before
+    public void setUp() {
+        model = new InsertDefinitionModel();
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.template.InsertDefinitionModel
+     * #execute(java.lang.String, java.lang.String, String,
+     * String, java.lang.String, java.lang.String, boolean, Request, ModelBody)}.
+     * @throws IOException If something goes wrong.
+     */
+    @Test
+    public void testExecute() throws IOException {
+        TilesContainer container = createMock(TilesContainer.class);
+        Request request = createMock(Request.class);
+        AttributeContext attributeContext = createMock(AttributeContext.class);
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+        requestScope.put(TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME, container);
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        ModelBody modelBody = createMock(ModelBody.class);
+
+        modelBody.evaluateWithoutWriting();
+        expect(request.getApplicationContext()).andReturn(applicationContext).times(2);
+        expect(request.getContext("request")).andReturn(requestScope).anyTimes();
+        expect(container.startContext(request)).andReturn(attributeContext);
+        expect(container.getAttributeContext(request)).andReturn(attributeContext);
+        container.endContext(request);
+        attributeContext.setPreparer("myPreparer");
+        attributeContext.setTemplateAttribute((Attribute) notNull());
+        container.render("myDefinitionName", request);
+
+        replay(container, attributeContext, request, applicationContext, modelBody);
+        model.execute("myDefinitionName", "myTemplate", "myTemplateType",
+                "myTemplateExpression", "myRole", "myPreparer",
+                false, request, modelBody);
+        verify(container, attributeContext, request, applicationContext, modelBody);
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-template/src/test/java/org/apache/tiles/template/InsertTemplateModelTest.java b/Java-base/tiles/src/tiles-template/src/test/java/org/apache/tiles/template/InsertTemplateModelTest.java
new file mode 100644
index 000000000..99b4fc1dd
--- /dev/null
+++ b/Java-base/tiles/src/tiles-template/src/test/java/org/apache/tiles/template/InsertTemplateModelTest.java
@@ -0,0 +1,91 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.template;
+
+import static org.easymock.EasyMock.*;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.AttributeContext;
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.access.TilesAccess;
+import org.apache.tiles.autotag.core.runtime.ModelBody;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.Request;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests {@link InsertTemplateModel}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class InsertTemplateModelTest {
+
+    /**
+     * The model to test.
+     */
+    private InsertTemplateModel model;
+
+    /**
+     * Sets up the test.
+     */
+    @Before
+    public void setUp() {
+        model = new InsertTemplateModel();
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.template.InsertTemplateModel
+     * #execute(String, String, String, String, String, boolean, Request, ModelBody)}.
+     * @throws IOException If something goes wrong.
+     */
+    @Test
+    public void testExecute() throws IOException {
+        TilesContainer container = createMock(TilesContainer.class);
+        Request request = createMock(Request.class);
+        AttributeContext attributeContext = createMock(AttributeContext.class);
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+        requestScope.put(TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME, container);
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        ModelBody modelBody = createMock(ModelBody.class);
+
+        modelBody.evaluateWithoutWriting();
+        expect(request.getApplicationContext()).andReturn(applicationContext).times(2);
+        expect(request.getContext("request")).andReturn(requestScope).anyTimes();
+        expect(container.startContext(request)).andReturn(attributeContext);
+        expect(container.getAttributeContext(request)).andReturn(attributeContext);
+        container.endContext(request);
+        attributeContext.setPreparer("myPreparer");
+        attributeContext.setTemplateAttribute((Attribute) notNull());
+        container.renderContext(request);
+
+        replay(container, attributeContext, request, applicationContext, modelBody);
+        model.execute("myTemplate", "myTemplateType", "myTemplateExpression",
+                "myRole", "myPreparer", false, request, modelBody);
+        verify(container, attributeContext, request, applicationContext, modelBody);
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-template/src/test/java/org/apache/tiles/template/PutAttributeModelTest.java b/Java-base/tiles/src/tiles-template/src/test/java/org/apache/tiles/template/PutAttributeModelTest.java
new file mode 100644
index 000000000..dafdf7691
--- /dev/null
+++ b/Java-base/tiles/src/tiles-template/src/test/java/org/apache/tiles/template/PutAttributeModelTest.java
@@ -0,0 +1,93 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.template;
+
+import static org.easymock.EasyMock.*;
+import static org.easymock.classextension.EasyMock.*;
+
+import java.io.IOException;
+import java.util.ArrayDeque;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.AttributeContext;
+import org.apache.tiles.ListAttribute;
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.access.TilesAccess;
+import org.apache.tiles.autotag.core.runtime.ModelBody;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.Request;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests {@link PutAttributeModel}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class PutAttributeModelTest {
+
+    /**
+     * The model to test.
+     */
+    private PutAttributeModel model;
+
+    /** Sets up the test. */
+    @Before
+    public void setUp() {
+        model = new PutAttributeModel();
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.template.PutAttributeModel
+     * #execute(String, Object, String, String, String,
+     * boolean, Request, ModelBody)}.
+     * @throws IOException If something goes wrong.
+     */
+    @Test
+    public void testExecuteListAttribute() throws IOException {
+        TilesContainer container = createMock(TilesContainer.class);
+        Request request = createMock(Request.class);
+        ModelBody modelBody = createMock(ModelBody.class);
+        AttributeContext attributeContext = createMock(AttributeContext.class);
+        Deque<Object> composeStack = new ArrayDeque<Object>();
+        ListAttribute listAttribute = new ListAttribute();
+        composeStack.push(listAttribute);
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+        requestScope.put(ComposeStackUtil.COMPOSE_STACK_ATTRIBUTE_NAME, composeStack);
+        requestScope.put(TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME, container);
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+
+        expect(request.getApplicationContext()).andReturn(applicationContext);
+        expect(request.getContext("request")).andReturn(requestScope).anyTimes();
+        expect(container.getAttributeContext(request)).andReturn(attributeContext);
+        attributeContext.putAttribute(eq("myName"), (Attribute) notNull(), eq(false));
+        expect(modelBody.evaluateAsString()).andReturn(null);
+
+        replay(container, attributeContext, request, applicationContext, modelBody);
+        model.execute("myName", "myValue", "myExpression", "myRole",
+                "myType", false, request, modelBody);
+        verify(container, attributeContext, request, applicationContext, modelBody);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-template/src/test/java/org/apache/tiles/template/PutListAttributeModelTest.java b/Java-base/tiles/src/tiles-template/src/test/java/org/apache/tiles/template/PutListAttributeModelTest.java
new file mode 100644
index 000000000..c147a6b16
--- /dev/null
+++ b/Java-base/tiles/src/tiles-template/src/test/java/org/apache/tiles/template/PutListAttributeModelTest.java
@@ -0,0 +1,93 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.template;
+
+import static org.easymock.EasyMock.*;
+import static org.easymock.classextension.EasyMock.*;
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.util.ArrayDeque;
+import java.util.Deque;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tiles.AttributeContext;
+import org.apache.tiles.ListAttribute;
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.access.TilesAccess;
+import org.apache.tiles.autotag.core.runtime.ModelBody;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.Request;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests {@link PutListAttributeModel}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class PutListAttributeModelTest {
+
+    /**
+     * The model to test.
+     */
+    private PutListAttributeModel model;
+
+    /**
+     * Sets up the test.
+     */
+    @Before
+    public void setUp() {
+        model = new PutListAttributeModel();
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.template.PutListAttributeModel
+     * #execute(String, String, boolean, boolean, Request, ModelBody)}.
+     * @throws IOException If something goes wrong.
+     */
+    @Test
+    public void testExecute() throws IOException {
+        TilesContainer container = createMock(TilesContainer.class);
+        AttributeContext attributeContext = createMock(AttributeContext.class);
+        Request request = createMock(Request.class);
+        Deque<Object> composeStack = new ArrayDeque<Object>();
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+        requestScope.put(ComposeStackUtil.COMPOSE_STACK_ATTRIBUTE_NAME, composeStack);
+        requestScope.put(TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME, container);
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        ModelBody modelBody = createMock(ModelBody.class);
+
+        modelBody.evaluateWithoutWriting();
+        expect(request.getApplicationContext()).andReturn(applicationContext);
+        expect(request.getContext("request")).andReturn(requestScope).anyTimes();
+        expect(container.getAttributeContext(request)).andReturn(attributeContext);
+        attributeContext.putAttribute(eq("myName"), isA(ListAttribute.class), eq(false));
+
+        replay(container, attributeContext, request, modelBody);
+        model.execute("myName", "myRole", false, false, request, modelBody);
+        assertEquals(0, composeStack.size());
+        verify(container, attributeContext, request, modelBody);
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-template/src/test/java/org/apache/tiles/template/SetCurrentContainerModelTest.java b/Java-base/tiles/src/tiles-template/src/test/java/org/apache/tiles/template/SetCurrentContainerModelTest.java
new file mode 100644
index 000000000..efacd4329
--- /dev/null
+++ b/Java-base/tiles/src/tiles-template/src/test/java/org/apache/tiles/template/SetCurrentContainerModelTest.java
@@ -0,0 +1,85 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.template;
+
+import static org.easymock.EasyMock.*;
+import static org.junit.Assert.*;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.tiles.NoSuchContainerException;
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.access.TilesAccess;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.Request;
+import org.junit.Test;
+
+/**
+ * Tests {@link SetCurrentContainerModel}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class SetCurrentContainerModelTest {
+
+    /**
+     * Test method for {@link SetCurrentContainerModel#execute(String, Request)}.
+     */
+    @Test
+    public void testSetCurrentContainer() {
+        Request request = createMock(Request.class);
+        ApplicationContext context = createMock(ApplicationContext.class);
+        TilesContainer container = createMock(TilesContainer.class);
+        Map<String, Object> attribs = new HashMap<String, Object>();
+        attribs.put("myKey", container);
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+
+        expect(context.getApplicationScope()).andReturn(attribs).anyTimes();
+        expect(request.getContext("request")).andReturn(requestScope);
+        expect(request.getApplicationContext()).andReturn(context);
+        replay(request, context, container);
+        SetCurrentContainerModel model = new SetCurrentContainerModel();
+        model.execute("myKey", request);
+        assertEquals(container, requestScope.get(TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME));
+        verify(request, context, container);
+    }
+
+    /**
+     * Test method for {@link SetCurrentContainerModel#execute(String, Request)}.
+     */
+    @Test(expected = NoSuchContainerException.class)
+    public void testSetCurrentContainerException() {
+        Request request = createMock(Request.class);
+        ApplicationContext context = createMock(ApplicationContext.class);
+        Map<String, Object> attribs = new HashMap<String, Object>();
+
+        expect(request.getApplicationContext()).andReturn(context);
+        expect(context.getApplicationScope()).andReturn(attribs).anyTimes();
+        replay(request, context);
+        try {
+            SetCurrentContainerModel model = new SetCurrentContainerModel();
+            model.execute("myKey", request);
+        } finally {
+            verify(request, context);
+        }
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-test-pom/pom.xml b/Java-base/tiles/src/tiles-test-pom/pom.xml
new file mode 100644
index 000000000..84dc19758
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/pom.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0"?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <artifactId>tiles-parent</artifactId>
+    <groupId>org.apache.tiles</groupId>
+    <version>3.1-SNAPSHOT</version>
+  </parent>
+  <artifactId>tiles-test-pom</artifactId>
+  <packaging>pom</packaging>
+  <name>Tiles test webapp module collector</name>
+  <description>Collects all the modules of the Tiles test web application.</description>
+  <modules>
+    <module>tiles-test-common</module>
+    <module>tiles-test-alt</module>
+    <module>tiles-test-db</module>
+  	<module>tiles-test</module>
+  </modules>
+</project>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/src/site/site.xml b/Java-base/tiles/src/tiles-test-pom/src/site/site.xml
new file mode 100644
index 000000000..6e87b5faa
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/src/site/site.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<project name="Apache Tiles - Test Webapp Module Collector">
+     <skin>
+        <groupId>org.apache.maven.skins</groupId>
+        <artifactId>maven-fluido-skin</artifactId>
+        <version>1.3.0</version>
+     </skin>
+     <custom>
+        <fluidoSkin>
+        <topBarEnabled>true</topBarEnabled>
+        <sideBarEnabled>false</sideBarEnabled>
+        <searchEnabled>true</searchEnabled>
+        <gitHub>
+            <projectId>apache/tiles</projectId>
+            <ribbonOrientation>right</ribbonOrientation>
+            <ribbonColor>darkblue</ribbonColor>
+        </gitHub>
+        </fluidoSkin>
+     </custom>
+    <bannerLeft>
+        <name>Apache Tiles&#8482;</name>
+        <src>http://tiles.apache.org/images/logo.png</src>
+        <href>http://tiles.apache.org</href>
+    </bannerLeft>
+    <bannerRight>
+        <name>Apache Software Foundation</name>
+        <src>http://struts.apache.org/images/asf-logo.gif</src>
+        <href>http://www.apache.org</href>
+    </bannerRight>
+    <body>
+
+        <menu name="Apache Tiles&#8482;">
+            <item
+                   name="Welcome"
+                   href="../../index.html"/>
+            <item
+                    name="Tiles 3.0.x"
+                    href="../../framework/index.html"/>
+            <item
+                    name="Autotag 1.0.x"
+                    href="../../tiles-autotag/index.html"/>
+            <item
+                    name="Request 1.0.x"
+                    href="../../tiles-request/index.html"/>
+            <item
+                   name="Security bulletins"
+                   href="../security/index.html"/>
+            <item
+                   name="Download"
+                   href="http://tiles.apache.org/download.html"/>
+        </menu>
+
+        <menu ref="modules" />
+        <menu ref="reports" />
+
+        <footer>
+            <div class="row span12">
+                Apache Tiles, Tiles, Apache, the Apache feather logo, and the Apache Tiles
+                project logos are trademarks of The Apache Software Foundation.
+            </div>
+        </footer>
+    </body>
+</project>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test-alt/pom.xml b/Java-base/tiles/src/tiles-test-pom/tiles-test-alt/pom.xml
new file mode 100644
index 000000000..3c0275d4c
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test-alt/pom.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <artifactId>tiles-test-pom</artifactId>
+    <groupId>org.apache.tiles</groupId>
+    <version>3.1-SNAPSHOT</version>
+  </parent>
+  <artifactId>tiles-test-alt</artifactId>
+  <name>Tiles - Test webapp alternate configuration</name>
+  <description>Alternate configuration for the test webapp.</description>
+  <properties>
+      <!-- decrease this whenever possible -->
+      <checkstyle.maxAllowedViolations>3</checkstyle.maxAllowedViolations>
+  </properties>
+
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-jar-plugin</artifactId>
+        <configuration>
+          <archive>
+            <manifestFile>${tiles.manifestfile}</manifestFile>
+            <manifest>
+              <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
+              <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+            </manifest>
+            <manifestEntries>
+              <Tiles-Initializer>org.apache.tiles.test.alt.TestAlternateTilesInitializer</Tiles-Initializer>
+            </manifestEntries>
+          </archive>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+  <dependencies>
+    <dependency>
+       <groupId>org.apache.tiles</groupId>
+       <artifactId>tiles-test-common</artifactId>
+       <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>javax.servlet</groupId>
+      <artifactId>servlet-api</artifactId>
+      <version>2.5</version>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test-alt/src/main/java/org/apache/tiles/test/alt/TestAlternateTilesContainerFactory.java b/Java-base/tiles/src/tiles-test-pom/tiles-test-alt/src/main/java/org/apache/tiles/test/alt/TestAlternateTilesContainerFactory.java
new file mode 100644
index 000000000..b164b4d62
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test-alt/src/main/java/org/apache/tiles/test/alt/TestAlternateTilesContainerFactory.java
@@ -0,0 +1,63 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.test.alt;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tiles.definition.dao.BaseLocaleUrlDefinitionDAO;
+import org.apache.tiles.definition.dao.CachingLocaleUrlDefinitionDAO;
+import org.apache.tiles.locale.LocaleResolver;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.ApplicationResource;
+import org.apache.tiles.test.factory.TestTilesContainerFactory;
+
+/**
+ * Test alternate Tiles container factory to customize Tiles behaviour.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TestAlternateTilesContainerFactory extends TestTilesContainerFactory {
+
+    /**
+     * The number of URLs to load..
+     */
+    private static final int URL_COUNT = 3;
+
+    /** {@inheritDoc} */
+    @Override
+    protected List<ApplicationResource> getSources(ApplicationContext applicationContext) {
+        List<ApplicationResource> urls = new ArrayList<ApplicationResource>(URL_COUNT);
+        urls.add(applicationContext.getResource("classpath:/org/apache/tiles/test/alt/defs/tiles-alt-defs.xml"));
+        urls.add(applicationContext.getResource("classpath:/org/apache/tiles/test/alt/defs/tiles-alt-freemarker-defs.xml"));
+        urls.add(applicationContext.getResource("classpath:/org/apache/tiles/test/alt/defs/tiles-alt-velocity-defs.xml"));
+        return urls;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected BaseLocaleUrlDefinitionDAO instantiateLocaleDefinitionDao(
+            ApplicationContext applicationContext,
+            LocaleResolver resolver) {
+        return new CachingLocaleUrlDefinitionDAO(applicationContext);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test-alt/src/main/java/org/apache/tiles/test/alt/TestAlternateTilesInitializer.java b/Java-base/tiles/src/tiles-test-pom/tiles-test-alt/src/main/java/org/apache/tiles/test/alt/TestAlternateTilesInitializer.java
new file mode 100644
index 000000000..291b639b7
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test-alt/src/main/java/org/apache/tiles/test/alt/TestAlternateTilesInitializer.java
@@ -0,0 +1,59 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.test.alt;
+
+import javax.servlet.ServletContext;
+
+import org.apache.tiles.factory.AbstractTilesContainerFactory;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.servlet.wildcard.WildcardServletApplicationContext;
+import org.apache.tiles.startup.AbstractTilesInitializer;
+
+/**
+ * Test Tiles initializer for Tiles initialization of the alternate container.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TestAlternateTilesInitializer extends AbstractTilesInitializer {
+
+    /** {@inheritDoc} */
+    @Override
+    protected AbstractTilesContainerFactory createContainerFactory(
+            ApplicationContext context) {
+        return new TestAlternateTilesContainerFactory();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected String getContainerKey(
+            ApplicationContext applicationContext) {
+        return "alternate";
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected ApplicationContext createTilesApplicationContext(
+            ApplicationContext preliminaryContext) {
+        return new WildcardServletApplicationContext(
+                (ServletContext) preliminaryContext.getContext());
+    }
+}
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test-alt/src/main/java/org/apache/tiles/test/alt/package.html b/Java-base/tiles/src/tiles-test-pom/tiles-test-alt/src/main/java/org/apache/tiles/test/alt/package.html
new file mode 100644
index 000000000..1a1be2061
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test-alt/src/main/java/org/apache/tiles/test/alt/package.html
@@ -0,0 +1,30 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+    <title>Alternate configuration for Tiles test webapp</title>
+</head>
+<body>
+An alternate configuration of the Tiles test webapp.
+</body>
+</html>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test-alt/src/main/resources/META-INF/MANIFEST.MF b/Java-base/tiles/src/tiles-test-pom/tiles-test-alt/src/main/resources/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..2c3725022
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test-alt/src/main/resources/META-INF/MANIFEST.MF
@@ -0,0 +1,31 @@
+Manifest-Version: 1.0
+Archiver-Version: Plexus Archiver
+Created-By: 1.6.0_16 (Sun Microsystems Inc.)
+Built-By: antonio
+Build-Jdk: 1.6.0_16
+Specification-Title: Tiles - Test webapp alternate configuration
+Specification-Version: 2.2.1-SNAPSHOT
+Specification-Vendor: Apache Software Foundation
+Implementation-Title: Tiles - Test webapp alternate configuration
+Implementation-Version: 2.2.1-SNAPSHOT
+Implementation-Vendor-Id: org.apache
+Implementation-Vendor: Apache Software Foundation
+Tiles-Initializer: org.apache.tiles.test.alt.TestAlternateTilesInitial
+ izer
+Export-Package: org.apache.tiles.test.alt;version="2.2.1.SNAPSHOT"
+Tool: Bnd-0.0.311
+Bundle-Name: Tiles - Test webapp alternate configuration
+Bundle-Vendor: Apache Software Foundation
+Bundle-Version: 2.2.1.SNAPSHOT
+Bnd-LastModified: 1254151613654
+Bundle-ManifestVersion: 2
+Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
+Bundle-Description: Alternate configuration for the test webapp.
+Import-Package: org.apache.tiles,org.apache.tiles.context,org.apache.t
+ iles.definition,org.apache.tiles.definition.dao,org.apache.tiles.fact
+ ory,org.apache.tiles.locale,org.apache.tiles.startup,org.apache.tiles
+ .test.alt;version="2.2",org.apache.tiles.test.factory
+Bundle-SymbolicName: org.apache.tiles-test-alt
+Bundle-DocURL: http://tiles.apache.org/framework/tiles-test-pom/tiles-
+ test-alt
+
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test-alt/src/main/resources/org/apache/tiles/test/alt/defs/tiles-alt-defs.xml b/Java-base/tiles/src/tiles-test-pom/tiles-test-alt/src/main/resources/org/apache/tiles/test/alt/defs/tiles-alt-defs.xml
new file mode 100644
index 000000000..b75fe3c2e
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test-alt/src/main/resources/org/apache/tiles/test/alt/defs/tiles-alt-defs.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 2.1//EN"
+       "http://tiles.apache.org/dtds/tiles-config_2_1.dtd">
+
+<tiles-definitions>
+  <definition name="test.definition" template="/layout.jsp">
+      <put-attribute name="title"  value="This definition is from an alternate container."/>
+      <put-attribute name="header" value="/header.jsp"/>
+      <put-attribute name="body"   value="/body.jsp"/>
+  </definition>
+  <definition name="WILDCARD:test.definition*.message*" template="/layout{1}.jsp">
+      <put-attribute name="title"  value="This definition has a message: {2}."/>
+      <put-attribute name="header" value="/header.jsp"/>
+      <put-attribute name="body"   value="/body.jsp"/>
+  </definition>
+  <definition name="REGEXP:test\.regexp\.definition(.*)\.message(.*)" template="/layout{1}.jsp">
+      <put-attribute name="title"  value="This definition has a message: {2}."/>
+      <put-attribute name="header" value="/header.jsp"/>
+      <put-attribute name="body"   value="/body.jsp"/>
+  </definition>
+</tiles-definitions>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test-alt/src/main/resources/org/apache/tiles/test/alt/defs/tiles-alt-freemarker-defs.xml b/Java-base/tiles/src/tiles-test-pom/tiles-test-alt/src/main/resources/org/apache/tiles/test/alt/defs/tiles-alt-freemarker-defs.xml
new file mode 100644
index 000000000..e230658a7
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test-alt/src/main/resources/org/apache/tiles/test/alt/defs/tiles-alt-freemarker-defs.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 2.1//EN"
+       "http://tiles.apache.org/dtds/tiles-config_2_1.dtd">
+
+<tiles-definitions>
+  <definition name="freemarker.test.definition" template="/freemarker/layout.ftl">
+      <put-attribute name="title"  value="This definition is from an alternate container."/>
+      <put-attribute name="header" value="/freemarker/header.ftl"/>
+      <put-attribute name="body"   value="/freemarker/body.ftl"/>
+  </definition>
+  <definition name="freemarker.test.definition.alt" template="/freemarker/layout.ftl">
+      <put-attribute name="title"  value="This definition is from an alternate container."/>
+      <put-attribute name="header" value="/freemarker/header.ftl"/>
+      <put-attribute name="body"   value="/org/apache/tiles/test/alt/freemarker/body.ftl"/>
+  </definition>
+  <definition name="WILDCARD:freemarker.test.definition*.message*" template="/freemarker/layout{1}.ftl">
+      <put-attribute name="title"  value="This definition has a message: {2}."/>
+      <put-attribute name="header" value="/freemarker/header.ftl"/>
+      <put-attribute name="body"   value="/freemarker/body.ftl"/>
+  </definition>
+  <definition name="REGEXP:freemarker\.test\.regexp\.definition(.*)\.message(.*)" template="/freemarker/layout{1}.ftl">
+      <put-attribute name="title"  value="This definition has a message: {2}."/>
+      <put-attribute name="header" value="/freemarker/header.ftl"/>
+      <put-attribute name="body"   value="/freemarker/body.ftl"/>
+  </definition>
+</tiles-definitions>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test-alt/src/main/resources/org/apache/tiles/test/alt/defs/tiles-alt-velocity-defs.xml b/Java-base/tiles/src/tiles-test-pom/tiles-test-alt/src/main/resources/org/apache/tiles/test/alt/defs/tiles-alt-velocity-defs.xml
new file mode 100644
index 000000000..f26dffe90
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test-alt/src/main/resources/org/apache/tiles/test/alt/defs/tiles-alt-velocity-defs.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 2.1//EN"
+       "http://tiles.apache.org/dtds/tiles-config_2_1.dtd">
+
+<tiles-definitions>
+  <definition name="velocity.test.definition" template="/velocity/layout.vm">
+      <put-attribute name="title"  value="This definition is from an alternate container."/>
+      <put-attribute name="header" value="/velocity/header.vm"/>
+      <put-attribute name="body"   value="/velocity/body.vm"/>
+  </definition>
+  <definition name="velocity.test.definition.alt" template="/velocity/layout.vm">
+      <put-attribute name="title"  value="This definition is from an alternate container."/>
+      <put-attribute name="header" value="/velocity/header.vm"/>
+      <put-attribute name="body"   value="/org/apache/tiles/test/alt/velocity/body.vm"/>
+  </definition>
+  <definition name="WILDCARD:velocity.test.definition*.message*" template="/velocity/layout{1}.vm">
+      <put-attribute name="title"  value="This definition has a message: {2}."/>
+      <put-attribute name="header" value="/velocity/header.vm"/>
+      <put-attribute name="body"   value="/velocity/body.vm"/>
+  </definition>
+  <definition name="REGEXP:velocity\.test\.regexp\.definition(.*)\.message(.*)" template="/velocity/layout{1}.vm">
+      <put-attribute name="title"  value="This definition has a message: {2}."/>
+      <put-attribute name="header" value="/velocity/header.vm"/>
+      <put-attribute name="body"   value="/velocity/body.vm"/>
+  </definition>
+</tiles-definitions>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test-alt/src/main/resources/org/apache/tiles/test/alt/freemarker/body.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test-alt/src/main/resources/org/apache/tiles/test/alt/freemarker/body.ftl
new file mode 100644
index 000000000..584a8644d
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test-alt/src/main/resources/org/apache/tiles/test/alt/freemarker/body.ftl
@@ -0,0 +1,24 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<div align="center"><b><i>This body is loaded from the "alt" module.</i></b></div>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test-alt/src/main/resources/org/apache/tiles/test/alt/freemarker/testinsertdefinition_alt.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test-alt/src/main/resources/org/apache/tiles/test/alt/freemarker/testinsertdefinition_alt.ftl
new file mode 100644
index 000000000..f8222962b
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test-alt/src/main/resources/org/apache/tiles/test/alt/freemarker/testinsertdefinition_alt.ftl
@@ -0,0 +1,25 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.setCurrentContainer containerKey="alternate" />
+<@tiles.insertDefinition name="freemarker.test.definition.alt" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test-alt/src/main/resources/org/apache/tiles/test/alt/velocity/body.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test-alt/src/main/resources/org/apache/tiles/test/alt/velocity/body.vm
new file mode 100644
index 000000000..abcd51b78
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test-alt/src/main/resources/org/apache/tiles/test/alt/velocity/body.vm
@@ -0,0 +1,22 @@
+#*
+ * $Id: body.vm 782137 2009-06-05 21:18:52Z apetrelli $
+ *
+ * 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.
+ *
+ *#
+<div align="center"><b><i>This body is loaded from the "alt" module.</i></b></div>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test-alt/src/main/resources/org/apache/tiles/test/alt/velocity/testinsertdefinition_alt.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test-alt/src/main/resources/org/apache/tiles/test/alt/velocity/testinsertdefinition_alt.vm
new file mode 100644
index 000000000..648bc0112
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test-alt/src/main/resources/org/apache/tiles/test/alt/velocity/testinsertdefinition_alt.vm
@@ -0,0 +1,23 @@
+#*
+ * $Id: testinsertdefinition.vm 782137 2009-06-05 21:18:52Z apetrelli $
+ *
+ * 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.
+ *
+ *#
+$tiles.setCurrentContainer("alternate")
+#tiles_insertDefinition({"name" : "velocity.test.definition.alt"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test-common/pom.xml b/Java-base/tiles/src/tiles-test-pom/tiles-test-common/pom.xml
new file mode 100644
index 000000000..94c4c67a4
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test-common/pom.xml
@@ -0,0 +1,47 @@
+<?xml version="1.0"?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <artifactId>tiles-test-pom</artifactId>
+    <groupId>org.apache.tiles</groupId>
+    <version>3.1-SNAPSHOT</version>
+  </parent>
+  <groupId>org.apache.tiles</groupId>
+  <artifactId>tiles-test-common</artifactId>
+  <version>3.1-SNAPSHOT</version>
+  <name>Tiles - Test webapp common classes</name>
+  <description>Common classes between modules of the test webapp.</description>
+  <properties>
+      <!-- decrease this whenever possible -->
+      <checkstyle.maxAllowedViolations>2</checkstyle.maxAllowedViolations>
+  </properties>
+  <dependencies>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>tiles-extras</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test-common/src/main/java/org/apache/tiles/test/factory/TestTilesContainerFactory.java b/Java-base/tiles/src/tiles-test-pom/tiles-test-common/src/main/java/org/apache/tiles/test/factory/TestTilesContainerFactory.java
new file mode 100644
index 000000000..1e057bdcd
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test-common/src/main/java/org/apache/tiles/test/factory/TestTilesContainerFactory.java
@@ -0,0 +1,69 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.test.factory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.evaluator.AttributeEvaluatorFactory;
+import org.apache.tiles.extras.complete.CompleteAutoloadTilesContainerFactory;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.ApplicationResource;
+import org.apache.tiles.request.render.BasicRendererFactory;
+import org.apache.tiles.test.renderer.ReverseStringRenderer;
+
+
+/**
+ * Test Tiles container factory to customize Tiles behaviour.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TestTilesContainerFactory extends CompleteAutoloadTilesContainerFactory {
+
+    /** {@inheritDoc} */
+    @Override
+    protected void registerAttributeRenderers(
+            BasicRendererFactory rendererFactory,
+            ApplicationContext applicationContext,
+            TilesContainer container,
+            AttributeEvaluatorFactory attributeEvaluatorFactory) {
+        super.registerAttributeRenderers(rendererFactory, applicationContext, container,
+                attributeEvaluatorFactory);
+        ReverseStringRenderer renderer = new ReverseStringRenderer();
+        rendererFactory.registerRenderer("reversed", renderer);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected List<ApplicationResource> getSources(ApplicationContext applicationContext) {
+        List<ApplicationResource> urls = new ArrayList<ApplicationResource>();
+        urls.addAll(applicationContext
+                .getResources("/WEB-INF/**/tiles-defs*.xml"));
+        urls.add(applicationContext.getResource(
+                "classpath:/org/apache/tiles/classpath-defs.xml"));
+        urls.add(applicationContext.getResource(
+                "classpath:/org/apache/tiles/freemarker-classpath-defs.xml"));
+        urls.add(applicationContext.getResource(
+            "classpath:/org/apache/tiles/velocity-classpath-defs.xml"));
+        return urls;
+    }
+}
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test-common/src/main/java/org/apache/tiles/test/renderer/ReverseStringRenderer.java b/Java-base/tiles/src/tiles-test-pom/tiles-test-common/src/main/java/org/apache/tiles/test/renderer/ReverseStringRenderer.java
new file mode 100644
index 000000000..67a699ba1
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test-common/src/main/java/org/apache/tiles/test/renderer/ReverseStringRenderer.java
@@ -0,0 +1,50 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.test.renderer;
+
+import java.io.IOException;
+
+import org.apache.tiles.request.Request;
+import org.apache.tiles.request.render.Renderer;
+
+/**
+ * A simple test <code>AttributeRenderer</code>.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ReverseStringRenderer implements Renderer {
+
+    /** {@inheritDoc} */
+    @Override
+    public void render(String value, Request request) throws IOException {
+        char[] array = value.toCharArray();
+        char[] newArray = new char[array.length];
+        for (int i = 0; i < array.length; i++) {
+            newArray[array.length - i - 1] = array[i];
+        }
+        request.getWriter().write(String.valueOf(newArray));
+    }
+
+    @Override
+    public boolean isRenderable(String path, Request request) {
+        return true;
+    }
+}
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test-common/src/main/java/org/apache/tiles/test/renderer/package.html b/Java-base/tiles/src/tiles-test-pom/tiles-test-common/src/main/java/org/apache/tiles/test/renderer/package.html
new file mode 100644
index 000000000..810bb9b70
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test-common/src/main/java/org/apache/tiles/test/renderer/package.html
@@ -0,0 +1,30 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+    <title>Tiles renderer test package</title>
+</head>
+<body>
+Test classes to check renderer functionality.
+</body>
+</html>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test-db/pom.xml b/Java-base/tiles/src/tiles-test-pom/tiles-test-db/pom.xml
new file mode 100644
index 000000000..7d7e0e9f2
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test-db/pom.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0"?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <artifactId>tiles-test-pom</artifactId>
+    <groupId>org.apache.tiles</groupId>
+    <version>3.1-SNAPSHOT</version>
+  </parent>
+  <artifactId>tiles-test-db</artifactId>
+  <name>Tiles - Test webapp database configuration</name>
+  <description>Tiles configuration that uses a database.</description>
+  <properties>
+      <!-- decrease this whenever possible -->
+      <checkstyle.maxAllowedViolations>2</checkstyle.maxAllowedViolations>
+  </properties>
+  <dependencies>
+    <dependency>
+       <groupId>org.apache.tiles</groupId>
+       <artifactId>tiles-test-common</artifactId>
+       <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.springframework</groupId>
+      <artifactId>spring-jdbc</artifactId>
+      <version>3.2.0.RELEASE</version>
+      <exclusions>
+        <exclusion>
+          <groupId>commons-logging</groupId>
+          <artifactId>commons-logging</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-jar-plugin</artifactId>
+        <configuration>
+          <archive>
+            <manifestFile>${tiles.manifestfile}</manifestFile>
+            <manifest>
+              <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
+              <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+            </manifest>
+            <manifestEntries>
+              <Tiles-Initializer>org.apache.tiles.test.db.TestDbTilesInitializer</Tiles-Initializer>
+            </manifestEntries>
+          </archive>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test-db/src/main/java/org/apache/tiles/test/db/LocaleDbDefinitionDAO.java b/Java-base/tiles/src/tiles-test-pom/tiles-test-db/src/main/java/org/apache/tiles/test/db/LocaleDbDefinitionDAO.java
new file mode 100644
index 000000000..5ad76f404
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test-db/src/main/java/org/apache/tiles/test/db/LocaleDbDefinitionDAO.java
@@ -0,0 +1,256 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.test.db;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.Definition;
+import org.apache.tiles.definition.dao.DefinitionDAO;
+import org.apache.tiles.request.locale.LocaleUtil;
+import org.springframework.jdbc.core.RowMapper;
+import org.springframework.jdbc.core.support.JdbcDaoSupport;
+
+/**
+ * Stub definition DAO to demonstrate that Tiles definitions can be stored in a
+ * Database.
+ *
+ * @version $Rev$ $Date$
+ */
+public class LocaleDbDefinitionDAO extends JdbcDaoSupport implements
+        DefinitionDAO<Locale> {
+
+    /**
+     * Selects a customization by its name.
+     */
+    private static final String SELECT_CUSTOMIZATION_BY_NAME_SQL =
+        "select ID, PARENT_ID, NAME from CUSTOMIZATION "
+            + "where NAME = ? ";
+
+    /**
+     * Selects a customization by its Id.
+     */
+    private static final String SELECT_CUSTOMIZATION_BY_ID_SQL =
+        "select ID, PARENT_ID, NAME from CUSTOMIZATION "
+            + "where ID = ? ";
+
+    /**
+     * Selects a definition by its name and a customization Id.
+     */
+    private static final String SELECT_DEFINITION_SQL =
+        "select ID, PARENT_NAME, NAME, PREPARER, TEMPLATE from DEFINITION "
+            + "where NAME = ? and CUSTOMIZATION_ID = ? ";
+
+    /**
+     * Selects attributes of a definition, given the definition Id.
+     */
+    private static final String SELECT_ATTRIBUTES_SQL =
+        "select ID, NAME, TYPE, VALUE, CASCADE_ATTRIBUTE from ATTRIBUTE "
+            + "where DEFINITION_ID = ? ";
+
+    /**
+     * Maps a row of a {@link ResultSet} to a {@link Definition}.
+     */
+    private final DefinitionRowMapper definitionRowMapper = new DefinitionRowMapper();
+
+    /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
+    public Definition getDefinition(String name, Locale locale) {
+        List<Map<String, Object>> customizations = null;
+        Long customizationId = null, parentCustomizationId = null;
+        do {
+            customizations = getJdbcTemplate().queryForList(
+                    SELECT_CUSTOMIZATION_BY_NAME_SQL,
+                    new Object[] { locale.toString() });
+            if (!customizations.isEmpty()) {
+                Map<String, Object> customization = customizations.get(0);
+                customizationId = ((Number) customization.get("ID")).longValue();
+                parentCustomizationId = numberToLong((Number) customization.get("PARENT_ID"));
+            } else {
+                locale = LocaleUtil.getParentLocale(locale);
+            }
+        } while (customizations.isEmpty());
+
+        return getDefinition(name, customizationId, parentCustomizationId,
+                locale);
+    }
+
+    /** {@inheritDoc} */
+    public Map<String, Definition> getDefinitions(Locale locale) {
+        throw new UnsupportedOperationException(
+                "Currently the 'getDefinitions' method is not supported");
+    }
+
+    /**
+     * Loads a definition from the DB.
+     *
+     * @param name The name of the definition.
+     * @param baseCustomizationId The id of the customization item.
+     * @param baseParentCustomizationId The id of the parent customization item.
+     * @param locale The locale.
+     * @return The definition.
+     */
+    @SuppressWarnings("unchecked")
+    protected DbDefinition getDefinition(String name, Long baseCustomizationId,
+            Long baseParentCustomizationId, @SuppressWarnings("unused") Locale locale) {
+        DbDefinition definition = null;
+        Long customizationId = baseCustomizationId;
+        Long parentCustomizationId = baseParentCustomizationId;
+        List<DbDefinition> definitions = null;
+        boolean finished = false;
+        do {
+            definitions = getJdbcTemplate()
+                    .query(SELECT_DEFINITION_SQL,
+                            new Object[] { name, customizationId },
+                            definitionRowMapper);
+            if (definitions.isEmpty()) {
+                if (parentCustomizationId != null) {
+                    Map<String, Object> customization = getJdbcTemplate().queryForMap(
+                            SELECT_CUSTOMIZATION_BY_ID_SQL,
+                            new Object[] { parentCustomizationId });
+                    customizationId = ((Number) customization.get("ID")).longValue();
+                    parentCustomizationId = numberToLong((Number) customization.get("PARENT_ID"));
+                } else {
+                    finished = true;
+                }
+            } else {
+                definition = definitions.get(0);
+                finished = true;
+            }
+        } while (!finished);
+
+        if (definition != null) {
+            AttributeRowMapper attributeRowMapper = new AttributeRowMapper(definition);
+            getJdbcTemplate().query(SELECT_ATTRIBUTES_SQL,
+                    new Object[] { definition.getId() }, attributeRowMapper);
+        }
+        return definition;
+    }
+
+    /**
+     * Returns a {@link Long} object only if the number is not null.
+     *
+     * @param number The number to convert.
+     * @return The number converted into {@link Long} if not null,
+     * <code>null</code> otherwise.
+     */
+    private static Long numberToLong(Number number) {
+        Long retValue = null;
+        if (number != null) {
+            retValue = number.longValue();
+        }
+        return retValue;
+    }
+
+    /**
+     * A definition with the new property "id".
+     */
+    private static class DbDefinition extends Definition {
+
+        /**
+         * The id of the definition.
+         */
+        private Long id;
+
+        /**
+         * The default constructor.
+         */
+        public DbDefinition() {
+            super();
+        }
+
+        /**
+         * Returns the Id of the definition.
+         *
+         * @return The id.
+         */
+        public Long getId() {
+            return id;
+        }
+
+        /**
+         * Sets the id of the definition.
+         *
+         * @param id The id to set
+         */
+        public void setId(Long id) {
+            this.id = id;
+        }
+
+    }
+
+    /**
+     * Maps a row of a {@link ResultSet} to a {@link Definition}.
+     */
+    private static final class DefinitionRowMapper implements RowMapper {
+
+        /** {@inheritDoc} */
+        public Object mapRow(ResultSet rs, int row) throws SQLException {
+            DbDefinition definition = new DbDefinition();
+            definition.setId(numberToLong((Number) rs.getObject("ID")));
+            definition.setName(rs.getString("NAME"));
+            definition.setTemplateAttribute(Attribute
+                    .createTemplateAttribute(rs.getString("TEMPLATE")));
+            definition.setPreparer(rs.getString("PREPARER"));
+            definition.setExtends(rs.getString("PARENT_NAME"));
+            return definition;
+        }
+
+    }
+
+    /**
+     * Maps a row of a {@link ResultSet} to an {@link Attribute}. It stores the
+     * attributes directly in their definition.
+     */
+    private static final class AttributeRowMapper implements RowMapper {
+
+        /**
+         * The definition in which the attributes will be stored.
+         */
+        private Definition definition;
+
+        /**
+         * Constructor.
+         *
+         * @param definition The definition in which the attributes will be
+         * stored.
+         */
+        private AttributeRowMapper(Definition definition) {
+            this.definition = definition;
+        }
+
+        /** {@inheritDoc} */
+        public Object mapRow(ResultSet rs, int row) throws SQLException {
+            Attribute attribute = new Attribute();
+            attribute.setRenderer(rs.getString("TYPE"));
+            attribute.setValue(rs.getString("VALUE"));
+            definition.putAttribute(rs.getString("NAME"), attribute, rs
+                    .getBoolean("CASCADE_ATTRIBUTE"));
+            return attribute;
+        }
+
+    }
+}
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test-db/src/main/java/org/apache/tiles/test/db/TestDbTilesContainerFactory.java b/Java-base/tiles/src/tiles-test-pom/tiles-test-db/src/main/java/org/apache/tiles/test/db/TestDbTilesContainerFactory.java
new file mode 100644
index 000000000..6cb63c496
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test-db/src/main/java/org/apache/tiles/test/db/TestDbTilesContainerFactory.java
@@ -0,0 +1,58 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.test.db;
+
+import java.util.Locale;
+
+import javax.sql.DataSource;
+
+import org.apache.tiles.definition.LocaleDefinitionsFactory;
+import org.apache.tiles.definition.dao.DefinitionDAO;
+import org.apache.tiles.factory.BasicTilesContainerFactory;
+import org.apache.tiles.locale.LocaleResolver;
+import org.apache.tiles.request.ApplicationContext;
+
+
+/**
+ * Test alternate Tiles container factory that uses a DB to store definitions.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TestDbTilesContainerFactory extends BasicTilesContainerFactory {
+
+    /** {@inheritDoc} */
+    @Override
+    protected DefinitionDAO<Locale> createLocaleDefinitionDao(ApplicationContext applicationContext,
+            LocaleResolver resolver) {
+        LocaleDbDefinitionDAO definitionDao = new LocaleDbDefinitionDAO();
+        definitionDao.setDataSource((DataSource) applicationContext
+                .getApplicationScope().get("dataSource"));
+        return definitionDao;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected LocaleDefinitionsFactory instantiateDefinitionsFactory(
+            ApplicationContext applicationContext, LocaleResolver resolver) {
+        return new LocaleDefinitionsFactory();
+    }
+}
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test-db/src/main/java/org/apache/tiles/test/db/TestDbTilesInitializer.java b/Java-base/tiles/src/tiles-test-pom/tiles-test-db/src/main/java/org/apache/tiles/test/db/TestDbTilesInitializer.java
new file mode 100644
index 000000000..43d436de7
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test-db/src/main/java/org/apache/tiles/test/db/TestDbTilesInitializer.java
@@ -0,0 +1,48 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.test.db;
+
+import org.apache.tiles.factory.AbstractTilesContainerFactory;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.startup.AbstractTilesInitializer;
+
+/**
+ * Test Tiles initializer for Tiles initialization of the db-based container.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TestDbTilesInitializer extends AbstractTilesInitializer {
+
+    /** {@inheritDoc} */
+    @Override
+    protected AbstractTilesContainerFactory createContainerFactory(
+            ApplicationContext context) {
+        return new TestDbTilesContainerFactory();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected String getContainerKey(
+            ApplicationContext applicationContext) {
+        return "db";
+    }
+}
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test-db/src/main/java/org/apache/tiles/test/db/package.html b/Java-base/tiles/src/tiles-test-pom/tiles-test-db/src/main/java/org/apache/tiles/test/db/package.html
new file mode 100644
index 000000000..eab996d2a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test-db/src/main/java/org/apache/tiles/test/db/package.html
@@ -0,0 +1,30 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+    <title>DB configuration for Tiles test webapp</title>
+</head>
+<body>
+A configuration based on a DBMS of the Tiles test webapp.
+</body>
+</html>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test-db/src/main/resources/META-INF/MANIFEST.MF b/Java-base/tiles/src/tiles-test-pom/tiles-test-db/src/main/resources/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..039fba106
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test-db/src/main/resources/META-INF/MANIFEST.MF
@@ -0,0 +1,32 @@
+Manifest-Version: 1.0
+Archiver-Version: Plexus Archiver
+Created-By: 1.6.0_16 (Sun Microsystems Inc.)
+Built-By: antonio
+Build-Jdk: 1.6.0_16
+Specification-Title: Tiles - Test webapp database configuration
+Specification-Version: 2.2.1-SNAPSHOT
+Specification-Vendor: Apache Software Foundation
+Implementation-Title: Tiles - Test webapp database configuration
+Implementation-Version: 2.2.1-SNAPSHOT
+Implementation-Vendor-Id: org.apache
+Implementation-Vendor: Apache Software Foundation
+Tiles-Initializer: org.apache.tiles.test.db.TestDbTilesInitializer
+Export-Package: org.apache.tiles.test.db;version="2.2.1.SNAPSHOT"
+Tool: Bnd-0.0.311
+Bundle-Name: Tiles - Test webapp database configuration
+Bundle-Vendor: Apache Software Foundation
+Bundle-Version: 2.2.1.SNAPSHOT
+Bnd-LastModified: 1254151614318
+Bundle-ManifestVersion: 2
+Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
+Bundle-Description: Tiles configuration that uses a database.
+Import-Package: javax.sql,org.apache.tiles,org.apache.tiles.context,or
+ g.apache.tiles.definition,org.apache.tiles.definition.dao,org.apache.
+ tiles.factory,org.apache.tiles.freemarker.context,org.apache.tiles.lo
+ cale,org.apache.tiles.test.db;version="2.2",org.apache.tiles.util,org
+ .apache.tiles.velocity.context,org.springframework.jdbc.core,org.spri
+ ngframework.jdbc.core.support
+Bundle-SymbolicName: org.apache.tiles-test-db
+Bundle-DocURL: http://tiles.apache.org/framework/tiles-test-pom/tiles-
+ test-db
+
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/pom.xml b/Java-base/tiles/src/tiles-test-pom/tiles-test/pom.xml
new file mode 100644
index 000000000..437d5f759
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/pom.xml
@@ -0,0 +1,468 @@
+<?xml version="1.0"?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+   <parent>
+      <groupId>org.apache.tiles</groupId>
+      <artifactId>tiles-test-pom</artifactId>
+      <version>3.1-SNAPSHOT</version>
+   </parent>
+
+   <modelVersion>4.0.0</modelVersion>
+   <artifactId>tiles-test</artifactId>
+   <packaging>war</packaging>
+   <name>Tiles - Apps - Test</name>
+   <description>Tiles Test web application: tests Tiles functionality.
+   </description>
+  <properties>
+      <!-- decrease this whenever possible -->
+      <checkstyle.maxAllowedViolations>8</checkstyle.maxAllowedViolations>
+  </properties>
+
+   <dependencies>
+      <dependency>
+         <groupId>org.apache.tiles</groupId>
+         <artifactId>tiles-test-common</artifactId>
+         <version>${project.version}</version>
+      </dependency>
+      <dependency>
+         <groupId>org.apache.tiles</groupId>
+         <artifactId>tiles-test-alt</artifactId>
+         <version>${project.version}</version>
+      </dependency>
+      <dependency>
+         <groupId>org.apache.tiles</groupId>
+         <artifactId>tiles-test-db</artifactId>
+         <version>${project.version}</version>
+      </dependency>
+      <dependency>
+         <groupId>org.apache.tiles</groupId>
+         <artifactId>tiles-extras</artifactId>
+         <version>${project.version}</version>
+      </dependency>
+      <dependency>
+         <groupId>org.apache.tiles</groupId>
+         <artifactId>tiles-request-portlet</artifactId>
+         <version>${tiles.request.version}</version>
+      </dependency>
+
+      <dependency>
+        <groupId>org.slf4j</groupId>
+        <artifactId>slf4j-jdk14</artifactId>
+        <scope>compile</scope>
+      </dependency>
+
+      <dependency>
+        <groupId>org.slf4j</groupId>
+        <artifactId>jcl-over-slf4j</artifactId>
+        <scope>compile</scope>
+      </dependency>
+
+      <dependency>
+         <groupId>javax.servlet</groupId>
+         <artifactId>servlet-api</artifactId>
+         <version>2.5</version>
+         <scope>provided</scope>
+      </dependency>
+      <dependency>
+         <groupId>javax.servlet.jsp</groupId>
+         <artifactId>jsp-api</artifactId>
+         <version>2.1</version>
+         <scope>provided</scope>
+      </dependency>
+      <dependency>
+         <groupId>javax.portlet</groupId>
+         <artifactId>portlet-api</artifactId>
+         <version>2.0</version>
+         <scope>provided</scope>
+      </dependency>
+      <dependency>
+         <groupId>javax.servlet</groupId>
+         <artifactId>jstl</artifactId>
+         <version>1.2</version>
+         <scope>runtime</scope>
+      </dependency>
+      <dependency>
+        <groupId>hsqldb</groupId>
+        <artifactId>hsqldb</artifactId>
+        <version>1.8.0.10</version>
+      </dependency>
+      <dependency>
+        <groupId>commons-io</groupId>
+        <artifactId>commons-io</artifactId>
+        <version>1.4</version>
+      </dependency>
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring-jdbc</artifactId>
+        <version>3.2.0.RELEASE</version>
+        <exclusions>
+          <exclusion>
+            <groupId>commons-logging</groupId>
+            <artifactId>commons-logging</artifactId>
+          </exclusion>
+        </exclusions>
+      </dependency>
+      <dependency>
+          <groupId>org.apache.portals.pluto</groupId>
+          <artifactId>pluto-taglib</artifactId>
+          <version>2.0.0</version>
+          <scope>provided</scope>
+      </dependency>
+   </dependencies>
+
+   <build>
+       <plugins>
+          <plugin>
+              <groupId>org.apache.maven.plugins</groupId>
+              <artifactId>maven-war-plugin</artifactId>
+              <version>2.4</version>
+              <configuration>
+                  <webResources>
+                      <resource>
+                          <directory>.</directory>
+                          <targetPath>META-INF</targetPath>
+                          <includes>
+                              <include>LICENSE.txt</include>
+                              <include>NOTICE.txt</include>
+                          </includes>
+                      </resource>
+                  </webResources>
+                  <archive>
+                      <manifest>
+                          <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
+                          <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+                      </manifest>
+                      <manifestEntries>
+                          <Tiles-Initializer>org.apache.tiles.test.init.TestTilesInitializer</Tiles-Initializer>
+                      </manifestEntries>
+                  </archive>
+               </configuration>
+           </plugin>
+           <plugin>
+               <groupId>org.codehaus.cargo</groupId>
+               <artifactId>cargo-maven2-plugin</artifactId>
+               <version>1.0.5</version>
+               <configuration>
+                   <container>
+                       <containerId>jetty7x</containerId>
+                       <type>embedded</type>
+                   </container>
+               </configuration>
+           </plugin>
+       </plugins>
+     <finalName>${project.artifactId}</finalName>
+   </build>
+
+    <profiles>
+        <profile>
+            <id>selenium</id>
+            <activation>
+                <property>
+                    <name>selenium</name>
+                </property>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>dependency-maven-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>unpack-selenium</id>
+                                <phase>generate-resources</phase>
+                                <goals>
+                                    <goal>unpack</goal>
+                                </goals>
+                                <configuration>
+                                    <artifactItems>
+                                        <artifactItem>
+                                            <groupId>org.openqa.selenium.core</groupId>
+                                            <artifactId>selenium-core</artifactId>
+                                            <version>1.0-beta-1</version>
+                                        </artifactItem>
+                                    </artifactItems>
+                                    <outputDirectory>${project.build.directory}/selenium</outputDirectory>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <artifactId>maven-antrun-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>copy-selenium</id>
+                                <phase>process-resources</phase>
+                                <configuration>
+                                    <tasks>
+                                        <copy todir="${project.build.directory}/${project.artifactId}/selenium/core">
+                                            <fileset dir="${project.build.directory}/selenium/core" />
+                                        </copy>
+                                        <copy todir="${project.build.directory}/${project.artifactId}/selenium/tests">
+                                            <fileset dir="src/test/selenium" />
+                                        </copy>
+                                    </tasks>
+                                </configuration>
+                                <goals>
+                                    <goal>run</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+            <repositories>
+                <repository>
+                    <id>OpenQA</id>
+                    <url>http://nexus.openqa.org/content/repositories/releases/</url>
+                </repository>
+            </repositories>
+        </profile>
+
+        <profile>
+            <id>run-selenium</id>
+            <activation>
+                <property>
+                    <name>run-selenium</name>
+                </property>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.codehaus.cargo</groupId>
+                        <artifactId>cargo-maven2-plugin</artifactId>
+                         <configuration>
+                            <container>
+                                <containerId>jetty7x</containerId>
+                                <type>embedded</type>
+                            </container>
+                            <wait>false</wait>
+                        </configuration>
+                        <executions>
+                            <execution>
+                                <id>start-container</id>
+                                <phase>pre-integration-test</phase>
+                                <goals>
+                                    <goal>start</goal>
+                                </goals>
+                            </execution>
+                            <execution>
+                                <id>stop-container</id>
+                                <phase>post-integration-test</phase>
+                                <goals>
+                                    <goal>stop</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                   </plugin>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>selenium-maven-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>run-tests</id>
+                                <phase>integration-test</phase>
+                                <goals>
+                                    <goal>selenese</goal>
+                                </goals>
+                                <configuration>
+                                    <background>true</background>
+                                    <browser>*googlechrome</browser>
+                                    <startURL>http://localhost:8080/tiles-test/</startURL>
+                                    <suite>src/test/selenium/TestSuite.html</suite>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-surefire-plugin</artifactId>
+                        <configuration>
+                            <!-- Skip the normal tests, we'll run them in the integration-test phase -->
+                            <skip>true</skip>
+                        </configuration>
+
+                        <executions>
+                            <execution>
+                                <phase>integration-test</phase>
+                                <goals>
+                                    <goal>test</goal>
+                                </goals>
+                                <configuration>
+                                    <skip>false</skip>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+
+        <profile>
+            <id>hostedqa</id>
+            <dependencies>
+                <dependency>
+                    <groupId>com.hostedqa</groupId>
+                    <artifactId>hostedqa-remote-ant</artifactId>
+                    <version>1.6.2</version>
+                    <scope>test</scope>
+                </dependency>
+            </dependencies>
+            <repositories>
+                <repository>
+                    <id>codehaus</id>
+                    <name>codehaus</name>
+                    <url>http://repository.codehaus.org</url>
+                </repository>
+                <repository>
+                    <id>maven-hostedqa</id>
+                    <name>maven-hostedqa</name>
+                    <snapshots>
+                        <enabled>true</enabled>
+                        <updatePolicy>always</updatePolicy>
+                        <checksumPolicy>ignore</checksumPolicy>
+                    </snapshots>
+                    <releases>
+                        <enabled>true</enabled>
+                    </releases>
+                    <url>http://maven.hostedqa.com</url>
+                </repository>
+            </repositories>
+            <build>
+                <plugins>
+                    <plugin>
+                        <artifactId>maven-antrun-plugin</artifactId>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <executions>
+                            <execution>
+                                <phase>package</phase>
+                                <goals>
+                                    <goal>run</goal>
+                                </goals>
+                                <configuration>
+                                    <tasks>
+                                        <taskdef resource="hostedqatasks" classpathref="maven.plugin.classpath" />
+                                        <upload file="${project.build.directory}/${project.build.finalName}.war" account="tiles" email="${tiles.hostedqa.email}" password="${tiles.hostedqa.password}" resourceId="${hostedqa.resourceId}" />
+
+                                        <playsuite clientConfigs="${hostedqa.clientConfigs}" appConfigs="${hostedqa.appConfigs}" account="tiles" email="${tiles.hostedqa.email}" password="${tiles.hostedqa.password}">
+                                            <fileSet dir="${basedir}/src/test/selenium" excludes="TestSuite.html" />
+                                        </playsuite>
+                                    </tasks>
+                                </configuration>
+                            </execution>
+                        </executions>
+                        <dependencies>
+                            <dependency>
+                                <groupId>com.hostedqa</groupId>
+                                <artifactId>hostedqa-remote-ant</artifactId>
+                                <version>1.6.2</version>
+                            </dependency>
+                        </dependencies>
+                    </plugin>
+                </plugins>
+            </build>
+            <properties>
+                <hostedqa.resourceId>53</hostedqa.resourceId>
+                <hostedqa.clientConfigs>303</hostedqa.clientConfigs>
+                <hostedqa.appConfigs>121</hostedqa.appConfigs>
+            </properties>
+        </profile>
+        <profile>
+            <id>apache-release</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>rat-maven-plugin</artifactId>
+                        <version>1.0-alpha-3</version>
+                        <executions>
+                            <execution>
+                                <phase>verify</phase>
+                                <goals>
+                                    <goal>check</goal>
+                                </goals>
+                                <configuration>
+                                    <addDefaultLicenseMatchers>false</addDefaultLicenseMatchers>
+                                    <licenseMatchers>
+                                        <classNames>
+                                            <className>rat.analysis.license.ApacheSoftwareLicense20</className>
+                                        </classNames>
+                                    </licenseMatchers>
+                                    <includes>
+                                        <include>pom.xml</include>
+                                        <include>src/**</include>
+                                    </includes>
+                                    <excludes>
+                                        <exclude>**/*.sql</exclude>
+                                        <exclude>**/*MANIFEST.MF</exclude>
+                                    </excludes>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>wagon-maven-plugin</artifactId>
+                        <version>1.0-beta-4</version>
+                        <executions>
+                            <execution>
+                                <phase>deploy</phase>
+                                <goals>
+                                    <goal>upload</goal>
+                                </goals>
+                                <configuration>
+                                    <fromDir>${settings.localRepository}/org/apache/tiles/tiles-test/${project.version}</fromDir>
+                                    <includes>tiles-test-${project.version}.war*</includes>
+                                    <toDir>${project.version}</toDir>
+                                    <serverId>tiles.build</serverId>
+                                    <url>scp://people.apache.org/www/people.apache.org/builds/tiles</url>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+    <repositories>
+        <repository>
+            <id>codehaus</id>
+            <name>codehaus</name>
+            <url>http://repository.codehaus.org</url>
+            <releases>
+                <enabled>true</enabled>
+            </releases>
+        </repository>
+    </repositories>
+    <pluginRepositories>
+        <pluginRepository>
+            <id>codehaus</id>
+            <name>codehaus</name>
+            <url>http://repository.codehaus.org</url>
+            <releases>
+                <enabled>true</enabled>
+            </releases>
+        </pluginRepository>
+    </pluginRepositories>
+</project>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/etc/db/project/tiles.architect b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/etc/db/project/tiles.architect
new file mode 100644
index 000000000..4a68575a5
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/etc/db/project/tiles.architect
@@ -0,0 +1,278 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<architect-project version="1.0" appversion="0.9.10">
+ <project-name>tiles</project-name>
+ <project-data-sources>
+  <data-source id="DS0">
+   <property key="Logical" value="Not Configured" />
+  </data-source>
+  <data-source id="DS2">
+   <property key="Connection Type" value="HSQLDB" />
+   <property key="Logical" value="Tiles in file" />
+   <property key="JDBC URL" value="jdbc:hsqldb:file:/home/antonio/javadev/db/tiles;shutdown=true" />
+   <property key="UID" value="sa" />
+   <property key="PWD" value="" />
+   <property key="ca.sqlpower.architect.etl.kettle.database" value="" />
+   <property key="ca.sqlpower.architect.etl.kettle.port" value="" />
+   <property key="ca.sqlpower.architect.etl.kettle.hostname" value="" />
+   <property key="ca.sqlpower.architect.etl.kettle.repos.login" value="" />
+   <property key="ca.sqlpower.architect.etl.kettle.repos.password" value="" />
+  </data-source>
+  <data-source id="DS2">
+   <property key="Connection Type" value="HSQLDB" />
+   <property key="Logical" value="Tiles in file" />
+   <property key="JDBC URL" value="jdbc:hsqldb:file:/home/antonio/javadev/db/tiles;shutdown=true" />
+   <property key="UID" value="sa" />
+   <property key="PWD" value="" />
+   <property key="ca.sqlpower.architect.etl.kettle.database" value="" />
+   <property key="ca.sqlpower.architect.etl.kettle.port" value="" />
+   <property key="ca.sqlpower.architect.etl.kettle.hostname" value="" />
+   <property key="ca.sqlpower.architect.etl.kettle.repos.login" value="" />
+   <property key="ca.sqlpower.architect.etl.kettle.repos.password" value="" />
+  </data-source>
+ </project-data-sources>
+ <source-databases>
+  <database id="DB0" populated="true" dbcs-ref="DS2" name="Tiles in file" physicalName="Tiles in memory" >
+   <schema id="SCH1" populated="false" name="INFORMATION_SCHEMA" nativeTerm="schema" physicalName="INFORMATION_SCHEMA" />
+   <schema id="SCH2" populated="true" name="PUBLIC" nativeTerm="schema" physicalName="PUBLIC" >
+    <table id="TAB3" populated="true" name="ATTRIBUTE" objectType="TABLE" physicalName="ATTRIBUTE" >
+     <folder id="FOL4" populated="false" name="Columns" physicalName="Columns" type="1" />
+     <folder id="FOL5" populated="false" name="Exported Keys" physicalName="Exported Keys" type="3" />
+     <folder id="FOL6" populated="false" name="Imported Keys" physicalName="Imported Keys" type="2" />
+     <folder id="FOL7" populated="false" name="Indices" physicalName="Indices" type="4" />
+    </table>
+    <table id="TAB8" populated="true" name="ATTRIBUTE_VISIBLE_FOR" objectType="TABLE" physicalName="ATTRIBUTE_VISIBLE_FOR" >
+     <folder id="FOL9" populated="false" name="Columns" physicalName="Columns" type="1" />
+     <folder id="FOL10" populated="false" name="Exported Keys" physicalName="Exported Keys" type="3" />
+     <folder id="FOL11" populated="false" name="Imported Keys" physicalName="Imported Keys" type="2" />
+     <folder id="FOL12" populated="false" name="Indices" physicalName="Indices" type="4" />
+    </table>
+    <table id="TAB13" populated="true" name="CUSTOMIZATION" objectType="TABLE" physicalName="CUSTOMIZATION" >
+     <folder id="FOL14" populated="false" name="Columns" physicalName="Columns" type="1" />
+     <folder id="FOL15" populated="false" name="Exported Keys" physicalName="Exported Keys" type="3" />
+     <folder id="FOL16" populated="false" name="Imported Keys" physicalName="Imported Keys" type="2" />
+     <folder id="FOL17" populated="false" name="Indices" physicalName="Indices" type="4" />
+    </table>
+    <table id="TAB18" populated="true" name="DEFINITION" objectType="TABLE" physicalName="DEFINITION" >
+     <folder id="FOL19" populated="false" name="Columns" physicalName="Columns" type="1" />
+     <folder id="FOL20" populated="false" name="Exported Keys" physicalName="Exported Keys" type="3" />
+     <folder id="FOL21" populated="false" name="Imported Keys" physicalName="Imported Keys" type="2" />
+     <folder id="FOL22" populated="false" name="Indices" physicalName="Indices" type="4" />
+    </table>
+    <table id="TAB23" populated="true" name="ROLE" objectType="TABLE" physicalName="ROLE" >
+     <folder id="FOL24" populated="false" name="Columns" physicalName="Columns" type="1" />
+     <folder id="FOL25" populated="false" name="Exported Keys" physicalName="Exported Keys" type="3" />
+     <folder id="FOL26" populated="false" name="Imported Keys" physicalName="Imported Keys" type="2" />
+     <folder id="FOL27" populated="false" name="Indices" physicalName="Indices" type="4" />
+    </table>
+    <table id="TAB28" populated="true" name="VISIBLE_FOR" objectType="TABLE" physicalName="VISIBLE_FOR" >
+     <folder id="FOL29" populated="false" name="Columns" physicalName="Columns" type="1" />
+     <folder id="FOL30" populated="false" name="Exported Keys" physicalName="Exported Keys" type="3" />
+     <folder id="FOL31" populated="false" name="Imported Keys" physicalName="Imported Keys" type="2" />
+     <folder id="FOL32" populated="false" name="Indices" physicalName="Indices" type="4" />
+    </table>
+   </schema>
+   <relationships>
+   </relationships>
+  </database>
+  <database id="DB33" populated="true" dbcs-ref="DS2" name="Tiles in file" physicalName="Tiles in file" >
+   <schema id="SCH34" populated="true" name="INFORMATION_SCHEMA" nativeTerm="schema" physicalName="INFORMATION_SCHEMA" >
+   </schema>
+   <schema id="SCH35" populated="true" name="PUBLIC" nativeTerm="schema" physicalName="PUBLIC" >
+   </schema>
+   <relationships>
+   </relationships>
+  </database>
+ </source-databases>
+ <target-database dbcs-ref="DS0">
+  <table id="TAB36" populated="true" name="Definition" objectType="TABLE" physicalName="Definition" remarks="" >
+   <folder id="FOL37" populated="true" name="Columns" physicalName="Columns" type="1" >
+    <column id="COL38" populated="true" autoIncrement="false" autoIncrementSequenceName="Definition_seq" name="id" nullable="0" physicalName="id" precision="12" primaryKeySeq="0" referenceCount="2" remarks="" scale="0" type="2" />
+    <column id="COL39" populated="true" autoIncrement="false" autoIncrementSequenceName="Definition_name_seq" name="name" nullable="0" physicalName="name" precision="255" referenceCount="1" remarks="" scale="0" type="12" />
+    <column id="COL40" populated="true" autoIncrement="false" autoIncrementSequenceName="Definition_preparer_seq" name="preparer" nullable="1" physicalName="preparer" precision="1000" referenceCount="1" remarks="" scale="0" type="12" />
+    <column id="COL41" populated="true" autoIncrement="false" autoIncrementSequenceName="Definition_template_seq" name="template" nullable="1" physicalName="template" precision="1000" referenceCount="1" remarks="" scale="0" type="12" />
+    <column id="COL42" populated="true" autoIncrement="false" autoIncrementSequenceName="Definition_Customization_id_seq" name="Customization_id" nullable="0" physicalName="Customization_id" precision="12" referenceCount="1" remarks="" scale="0" type="2" />
+    <column id="COL43" populated="true" autoIncrement="false" autoIncrementSequenceName="Definition_parent_name_seq" name="parent_name" nullable="1" physicalName="parent_name" precision="255" referenceCount="1" remarks="" scale="0" type="12" />
+   </folder>
+   <folder id="FOL44" populated="true" name="Exported Keys" physicalName="Exported Keys" type="3" >
+   </folder>
+   <folder id="FOL45" populated="true" name="Imported Keys" physicalName="Imported Keys" type="2" >
+   </folder>
+   <folder id="FOL46" populated="true" name="Indices" physicalName="Indices" type="4" >
+    <index id="IDX47" populated="true" clustered="false" name="Definition_pk" physicalName="Definition_pk" primaryKeyIndex="true" unique="true" >
+     <index-column id="IDC48" populated="true" ascendingOrDescending="UNSPECIFIED" column-ref="COL38" name="id" physicalName="id" />
+    </index>
+    <index id="IDX49" populated="true" clustered="false" name="Definition_idx" physicalName="Definition_idx" primaryKeyIndex="false" unique="false" >
+     <index-column id="IDC50" populated="true" ascendingOrDescending="ASCENDING" column-ref="COL39" name="name" physicalName="name" />
+    </index>
+   </folder>
+  </table>
+  <table id="TAB51" populated="true" name="Attribute" objectType="TABLE" physicalName="Attribute" remarks="" >
+   <folder id="FOL52" populated="true" name="Columns" physicalName="Columns" type="1" >
+    <column id="COL53" populated="true" autoIncrement="false" autoIncrementSequenceName="Attribute_seq" name="id" nullable="0" physicalName="id" precision="12" primaryKeySeq="0" referenceCount="2" remarks="" scale="0" type="2" />
+    <column id="COL54" populated="true" autoIncrement="false" autoIncrementSequenceName="Attribute_name_seq" name="name" nullable="0" physicalName="name" precision="255" referenceCount="1" remarks="" scale="0" type="12" />
+    <column id="COL55" populated="true" autoIncrement="false" autoIncrementSequenceName="Attribute_type_seq" name="type" nullable="1" physicalName="type" precision="255" referenceCount="1" remarks="" scale="0" type="12" />
+    <column id="COL56" populated="true" autoIncrement="false" autoIncrementSequenceName="Attribute_value_seq" name="value" nullable="0" physicalName="value" precision="1000" referenceCount="1" remarks="" scale="0" type="12" />
+    <column id="COL57" populated="true" autoIncrement="false" autoIncrementSequenceName="Attribute_cascade_attribute_seq" name="cascade_attribute" nullable="0" physicalName="cascade_attribute" precision="10" referenceCount="1" remarks="" scale="0" type="16" />
+    <column id="COL58" populated="true" autoIncrement="false" autoIncrementSequenceName="Attribute_Definition_id_seq" name="Definition_id" nullable="1" physicalName="Definition_id" precision="12" referenceCount="1" remarks="" scale="0" type="2" />
+    <column id="COL59" populated="true" autoIncrement="false" autoIncrementSequenceName="Attribute_seq" name="Parent_id" nullable="1" physicalName="Parent_id" precision="12" referenceCount="1" remarks="" scale="0" type="2" />
+   </folder>
+   <folder id="FOL60" populated="true" name="Exported Keys" physicalName="Exported Keys" type="3" >
+   </folder>
+   <folder id="FOL61" populated="true" name="Imported Keys" physicalName="Imported Keys" type="2" >
+   </folder>
+   <folder id="FOL62" populated="true" name="Indices" physicalName="Indices" type="4" >
+    <index id="IDX63" populated="true" clustered="false" name="Attribute_pk" physicalName="Attribute_pk" primaryKeyIndex="true" unique="true" >
+     <index-column id="IDC64" populated="true" ascendingOrDescending="UNSPECIFIED" column-ref="COL53" name="id" physicalName="id" />
+    </index>
+   </folder>
+  </table>
+  <table id="TAB65" populated="true" name="Role" objectType="TABLE" physicalName="Role" remarks="" >
+   <folder id="FOL66" populated="true" name="Columns" physicalName="Columns" type="1" >
+    <column id="COL67" populated="true" autoIncrement="false" autoIncrementSequenceName="Role_seq" name="id" nullable="0" physicalName="id" precision="12" primaryKeySeq="0" referenceCount="1" remarks="" scale="0" type="2" />
+    <column id="COL68" populated="true" autoIncrement="false" autoIncrementSequenceName="Role_name_seq" name="name" nullable="0" physicalName="name" precision="255" referenceCount="1" remarks="" scale="0" type="12" />
+   </folder>
+   <folder id="FOL69" populated="true" name="Exported Keys" physicalName="Exported Keys" type="3" >
+   </folder>
+   <folder id="FOL70" populated="true" name="Imported Keys" physicalName="Imported Keys" type="2" >
+   </folder>
+   <folder id="FOL71" populated="true" name="Indices" physicalName="Indices" type="4" >
+    <index id="IDX72" populated="true" clustered="false" name="Role_pk" physicalName="Role_pk" primaryKeyIndex="true" unique="true" >
+     <index-column id="IDC73" populated="true" ascendingOrDescending="UNSPECIFIED" column-ref="COL67" name="id" physicalName="id" />
+    </index>
+    <index id="IDX74" populated="true" clustered="false" name="Role_idx" physicalName="Role_idx" primaryKeyIndex="false" unique="false" >
+     <index-column id="IDC75" populated="true" ascendingOrDescending="ASCENDING" column-ref="COL68" name="name" physicalName="name" />
+    </index>
+   </folder>
+  </table>
+  <table id="TAB76" populated="true" name="Customization" objectType="TABLE" physicalName="Customization" remarks="" >
+   <folder id="FOL77" populated="true" name="Columns" physicalName="Columns" type="1" >
+    <column id="COL78" populated="true" autoIncrement="false" autoIncrementSequenceName="Customization_seq" name="id" nullable="0" physicalName="id" precision="12" primaryKeySeq="0" referenceCount="1" remarks="" scale="0" type="2" />
+    <column id="COL79" populated="true" autoIncrement="false" autoIncrementSequenceName="Customization_seq" name="Parent_id" nullable="1" physicalName="Parent_id" precision="12" referenceCount="1" remarks="" scale="0" type="2" />
+    <column id="COL80" populated="true" autoIncrement="false" autoIncrementSequenceName="Customization_name_seq" name="name" nullable="0" physicalName="name" precision="255" referenceCount="1" remarks="" scale="0" type="12" />
+   </folder>
+   <folder id="FOL81" populated="true" name="Exported Keys" physicalName="Exported Keys" type="3" >
+   </folder>
+   <folder id="FOL82" populated="true" name="Imported Keys" physicalName="Imported Keys" type="2" >
+   </folder>
+   <folder id="FOL83" populated="true" name="Indices" physicalName="Indices" type="4" >
+    <index id="IDX84" populated="true" clustered="false" name="Customization_pk" physicalName="Customization_pk" primaryKeyIndex="true" unique="true" >
+     <index-column id="IDC85" populated="true" ascendingOrDescending="UNSPECIFIED" column-ref="COL78" name="id" physicalName="id" />
+    </index>
+    <index id="IDX86" populated="true" clustered="false" name="Customization_idx" physicalName="Customization_idx" primaryKeyIndex="false" unique="false" >
+     <index-column id="IDC87" populated="true" ascendingOrDescending="ASCENDING" column-ref="COL80" name="name" physicalName="name" />
+    </index>
+    <index id="IDX88" populated="true" clustered="false" name="Customization_idx1" physicalName="Customization_idx1" primaryKeyIndex="false" unique="false" >
+     <index-column id="IDC89" populated="true" ascendingOrDescending="ASCENDING" column-ref="COL80" name="name" physicalName="name" />
+    </index>
+   </folder>
+  </table>
+  <table id="TAB90" populated="true" name="Visible_for" objectType="TABLE" physicalName="Visible_for" remarks="" >
+   <folder id="FOL91" populated="true" name="Columns" physicalName="Columns" type="1" >
+    <column id="COL92" populated="true" autoIncrement="false" autoIncrementSequenceName="Definition_seq" name="Definition_id" nullable="0" physicalName="Definition_id" precision="12" primaryKeySeq="0" referenceCount="1" remarks="" scale="0" type="2" />
+    <column id="COL93" populated="true" autoIncrement="false" autoIncrementSequenceName="Role_seq" name="Role_id" nullable="0" physicalName="Role_id" precision="12" primaryKeySeq="1" referenceCount="1" remarks="" scale="0" type="2" />
+   </folder>
+   <folder id="FOL94" populated="true" name="Exported Keys" physicalName="Exported Keys" type="3" >
+   </folder>
+   <folder id="FOL95" populated="true" name="Imported Keys" physicalName="Imported Keys" type="2" >
+   </folder>
+   <folder id="FOL96" populated="true" name="Indices" physicalName="Indices" type="4" >
+    <index id="IDX97" populated="true" clustered="false" name="Visible_for_pk" physicalName="Visible_for_pk" primaryKeyIndex="true" unique="true" >
+     <index-column id="IDC98" populated="true" ascendingOrDescending="UNSPECIFIED" column-ref="COL92" name="Definition_id" physicalName="Definition_id" />
+     <index-column id="IDC99" populated="true" ascendingOrDescending="UNSPECIFIED" column-ref="COL93" name="Role_id" physicalName="Role_id" />
+    </index>
+   </folder>
+  </table>
+  <table id="TAB100" populated="true" name="Attribute_visible_for" objectType="TABLE" physicalName="Attribute_visible_for" remarks="" >
+   <folder id="FOL101" populated="true" name="Columns" physicalName="Columns" type="1" >
+    <column id="COL102" populated="true" autoIncrement="false" autoIncrementSequenceName="Attribute_seq" name="Attribute_id" nullable="0" physicalName="Attribute_id" precision="12" primaryKeySeq="0" referenceCount="1" remarks="" scale="0" type="2" />
+    <column id="COL103" populated="true" autoIncrement="false" autoIncrementSequenceName="Role_seq" name="Role_id" nullable="0" physicalName="Role_id" precision="12" primaryKeySeq="1" referenceCount="1" remarks="" scale="0" type="2" />
+   </folder>
+   <folder id="FOL104" populated="true" name="Exported Keys" physicalName="Exported Keys" type="3" >
+   </folder>
+   <folder id="FOL105" populated="true" name="Imported Keys" physicalName="Imported Keys" type="2" >
+   </folder>
+   <folder id="FOL106" populated="true" name="Indices" physicalName="Indices" type="4" >
+    <index id="IDX107" populated="true" clustered="false" name="Attribute_visible_for_pk" physicalName="Attribute_visible_for_pk" primaryKeyIndex="true" unique="true" >
+     <index-column id="IDC108" populated="true" ascendingOrDescending="UNSPECIFIED" column-ref="COL102" name="Attribute_id" physicalName="Attribute_id" />
+     <index-column id="IDC109" populated="true" ascendingOrDescending="UNSPECIFIED" column-ref="COL103" name="Role_id" physicalName="Role_id" />
+    </index>
+   </folder>
+  </table>
+  <relationships>
+   <relationship id="REL110" populated="true" deferrability="7" deleteRule="0" fk-table-ref="TAB51" fkCardinality="7" identifying="false" name="Definition_Attribute_fk" physicalName="Definition_Attribute_fk" pk-table-ref="TAB36" pkCardinality="3" updateRule="0" >
+    <column-mapping id="CMP111" populated="true" fk-column-ref="COL58" name="Column Mapping" physicalName="Column Mapping" pk-column-ref="COL38" />
+   </relationship>
+   <relationship id="REL112" populated="true" deferrability="7" deleteRule="0" fk-table-ref="TAB90" fkCardinality="7" identifying="true" name="Definition_Visible_for_fk" physicalName="Definition_Visible_for_fk" pk-table-ref="TAB36" pkCardinality="2" updateRule="0" >
+    <column-mapping id="CMP113" populated="true" fk-column-ref="COL92" name="Column Mapping" physicalName="Column Mapping" pk-column-ref="COL38" />
+   </relationship>
+   <relationship id="REL114" populated="true" deferrability="7" deleteRule="0" fk-table-ref="TAB36" fkCardinality="7" identifying="true" name="Customization_Definition_fk" physicalName="Customization_Definition_fk" pk-table-ref="TAB76" pkCardinality="2" updateRule="0" >
+    <column-mapping id="CMP115" populated="true" fk-column-ref="COL42" name="Column Mapping" physicalName="Column Mapping" pk-column-ref="COL78" />
+   </relationship>
+   <relationship id="REL116" populated="true" deferrability="7" deleteRule="0" fk-table-ref="TAB51" fkCardinality="7" identifying="false" name="Attribute_Attribute_fk" physicalName="Attribute_Attribute_fk" pk-table-ref="TAB51" pkCardinality="3" updateRule="0" >
+    <column-mapping id="CMP117" populated="true" fk-column-ref="COL59" name="Column Mapping" physicalName="Column Mapping" pk-column-ref="COL53" />
+   </relationship>
+   <relationship id="REL118" populated="true" deferrability="7" deleteRule="0" fk-table-ref="TAB100" fkCardinality="7" identifying="true" name="Attribute_Attribute_visible_for_fk" physicalName="Attribute_Attribute_visible_for_fk" pk-table-ref="TAB51" pkCardinality="2" updateRule="0" >
+    <column-mapping id="CMP119" populated="true" fk-column-ref="COL102" name="Column Mapping" physicalName="Column Mapping" pk-column-ref="COL53" />
+   </relationship>
+   <reference ref-id="REL110" />
+   <reference ref-id="REL116" />
+   <relationship id="REL120" populated="true" deferrability="7" deleteRule="0" fk-table-ref="TAB90" fkCardinality="7" identifying="true" name="Role_Visible_for_fk" physicalName="Role_Visible_for_fk" pk-table-ref="TAB65" pkCardinality="2" updateRule="0" >
+    <column-mapping id="CMP121" populated="true" fk-column-ref="COL93" name="Column Mapping" physicalName="Column Mapping" pk-column-ref="COL67" />
+   </relationship>
+   <relationship id="REL122" populated="true" deferrability="7" deleteRule="0" fk-table-ref="TAB100" fkCardinality="7" identifying="true" name="Role_Attribute_visible_for_fk" physicalName="Role_Attribute_visible_for_fk" pk-table-ref="TAB65" pkCardinality="2" updateRule="0" >
+    <column-mapping id="CMP123" populated="true" fk-column-ref="COL103" name="Column Mapping" physicalName="Column Mapping" pk-column-ref="COL67" />
+   </relationship>
+   <reference ref-id="REL114" />
+   <relationship id="REL124" populated="true" deferrability="7" deleteRule="0" fk-table-ref="TAB76" fkCardinality="7" identifying="false" name="Customization_Customization_fk" physicalName="Customization_Customization_fk" pk-table-ref="TAB76" pkCardinality="3" updateRule="0" >
+    <column-mapping id="CMP125" populated="true" fk-column-ref="COL79" name="Column Mapping" physicalName="Column Mapping" pk-column-ref="COL78" />
+   </relationship>
+   <reference ref-id="REL124" />
+   <reference ref-id="REL112" />
+   <reference ref-id="REL120" />
+   <reference ref-id="REL118" />
+   <reference ref-id="REL122" />
+  </relationships>
+ </target-database>
+ <ddl-generator type="ca.sqlpower.architect.ddl.HSQLDBDDLGenerator" allow-connection="false" target-schema="public"> </ddl-generator>
+ <create-kettle-job-settings filePath="" jobName="" schemaName="" kettleJoinType="0" savingToFile="true" />
+ <play-pen zoom="1.0" viewportX="0" viewportY="0" relationship-style="rectilinear">
+  <table-pane table-ref="TAB36" x="234" y="51" />
+  <table-pane table-ref="TAB51" x="700" y="53" />
+  <table-pane table-ref="TAB65" x="729" y="488" />
+  <table-pane table-ref="TAB76" x="217" y="457" />
+  <table-pane table-ref="TAB90" x="481" y="321" />
+  <table-pane table-ref="TAB100" x="748" y="319" />
+  <table-link relationship-ref="REL110" pk-x="187" pk-y="45" fk-x="0" fk-y="43" orientation="33" />
+  <table-link relationship-ref="REL116" pk-x="33" pk-y="143" fk-x="0" fk-y="82" orientation="36" />
+  <table-link relationship-ref="REL114" pk-x="56" pk-y="0" fk-x="39" fk-y="120" orientation="72" />
+  <table-link relationship-ref="REL124" pk-x="70" pk-y="79" fk-x="0" fk-y="39" orientation="36" />
+  <table-link relationship-ref="REL112" pk-x="95" pk-y="120" fk-x="0" fk-y="28" orientation="36" />
+  <table-link relationship-ref="REL120" pk-x="0" pk-y="33" fk-x="44" fk-y="63" orientation="66" />
+  <table-link relationship-ref="REL118" pk-x="70" pk-y="143" fk-x="84" fk-y="0" orientation="132" />
+  <table-link relationship-ref="REL122" pk-x="64" pk-y="0" fk-x="45" fk-y="63" orientation="72" />
+ </play-pen>
+ <profiles topNCount="10">
+  </profiles>
+</architect-project>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/exception/TilesTestRuntimeException.java b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/exception/TilesTestRuntimeException.java
new file mode 100644
index 000000000..adabdeeb4
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/exception/TilesTestRuntimeException.java
@@ -0,0 +1,65 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.test.exception;
+
+/**
+ * Runtime exception used during the execution of the test web application.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TilesTestRuntimeException extends RuntimeException {
+
+    /**
+     * Constructor.
+     */
+    public TilesTestRuntimeException() {
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param message The message of the exception.
+     */
+    public TilesTestRuntimeException(String message) {
+        super(message);
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param cause The cause of the exception.
+     */
+    public TilesTestRuntimeException(Throwable cause) {
+        super(cause);
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param message The message of the exception.
+     * @param cause The cause of the exception.
+     */
+    public TilesTestRuntimeException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/exception/package.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/exception/package.html
new file mode 100644
index 000000000..54446b89b
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/exception/package.html
@@ -0,0 +1,30 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+    <title>Tiles test exceptions</title>
+</head>
+<body>
+Exceptions raised during the execution of the test web application.
+</body>
+</html>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/filter/SecurityWrappingFilter.java b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/filter/SecurityWrappingFilter.java
new file mode 100644
index 000000000..8eb4cab89
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/filter/SecurityWrappingFilter.java
@@ -0,0 +1,86 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.test.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.HttpServletRequestWrapper;
+
+/**
+ * Filter that wraps an HttpServletRequest to override "isUserInRole".
+ *
+ * @version $Rev$ $Date$
+ */
+public class SecurityWrappingFilter implements Filter {
+
+    /**
+     * The role that the current user is supposed to use.
+     */
+    public static final String GOOD_ROLE = "goodrole";
+
+    /** {@inheritDoc} */
+    public void init(FilterConfig filterConfig) throws ServletException {
+        // No operation
+    }
+
+    /** {@inheritDoc} */
+    public void doFilter(ServletRequest servletRequest,
+            ServletResponse servletResponse, FilterChain filterChain)
+            throws IOException, ServletException {
+        HttpServletRequest wrappedRequest = new SecurityWrapperHttpServletRequest(
+                (HttpServletRequest) servletRequest);
+        filterChain.doFilter(wrappedRequest, servletResponse);
+    }
+
+    /** {@inheritDoc} */
+    public void destroy() {
+        // No operation
+    }
+
+    /**
+     * Request wrapper that overrides "isUserInRole" method.
+     *
+     * @version $Rev$ $Date$
+     */
+    private static class SecurityWrapperHttpServletRequest extends
+            HttpServletRequestWrapper {
+        /**
+         * Constructor.
+         *
+         * @param request The HTTP servlet request.
+         */
+        public SecurityWrapperHttpServletRequest(HttpServletRequest request) {
+            super(request);
+        }
+
+        /** {@inheritDoc} */
+        @Override
+        public boolean isUserInRole(String role) {
+            return GOOD_ROLE.equals(role);
+        }
+    }
+}
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/filter/package.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/filter/package.html
new file mode 100644
index 000000000..8104a786e
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/filter/package.html
@@ -0,0 +1,30 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+    <title>Tiles filter test package</title>
+</head>
+<body>
+Contains filter to be used in the test web application.
+</body>
+</html>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/init/InitContextListener.java b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/init/InitContextListener.java
new file mode 100644
index 000000000..41efda081
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/init/InitContextListener.java
@@ -0,0 +1,138 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.test.init;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+import javax.sql.DataSource;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.tiles.test.exception.TilesTestRuntimeException;
+import org.hsqldb.jdbc.jdbcDataSource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Initializes the data source of the DB.
+ *
+ * @version $Rev$ $Date$
+ */
+public class InitContextListener implements ServletContextListener {
+
+    /**
+     * The logging object.
+     */
+    private final Logger log = LoggerFactory
+            .getLogger(InitContextListener.class);
+
+    /** {@inheritDoc} */
+    public void contextInitialized(ServletContextEvent event) {
+        DataSource dataSource = createDataSource();
+        event.getServletContext().setAttribute("dataSource", dataSource);
+        String[] commands = getSQLCommands();
+        executeCommands(dataSource, commands);
+    }
+
+    /** {@inheritDoc} */
+    public void contextDestroyed(ServletContextEvent event) {
+        // Do nothing
+    }
+
+    /**
+     * Creates the data source to use.
+     *
+     * @return The data source.
+     */
+    private DataSource createDataSource() {
+        jdbcDataSource dataSource = new jdbcDataSource();
+        dataSource.setDatabase("jdbc:hsqldb:mem:tiles");
+        dataSource.setUser("sa");
+        dataSource.setPassword("");
+        return dataSource;
+    }
+
+    /**
+     * Loads and returns the SQL commands to initialize the DB.
+     *
+     * @return The SQL commands to execute.
+     */
+    private String[] getSQLCommands() {
+        InputStream stream = getClass().getResourceAsStream(
+                "/org/apache/tiles/test/db/schema.sql");
+        String text;
+        try {
+            text = IOUtils.toString(stream);
+        } catch (IOException e) {
+            throw new TilesTestRuntimeException("Cannot read schema SQL text", e);
+        } finally {
+            try {
+                stream.close();
+            } catch (IOException e) {
+                log.error("Error during close of the stream containing the SQL schema", e);
+            }
+        }
+        return text.split(";");
+    }
+
+    /**
+     * Execute SQL commands.
+     *
+     * @param dataSource The data source to use.
+     * @param commands The commands to execute.
+     */
+    private void executeCommands(DataSource dataSource, String[] commands) {
+        Connection conn = null;
+        Statement stmt = null;
+        try {
+            conn = dataSource.getConnection();
+            for (int i = 0; i < commands.length; i++) {
+                stmt = conn.createStatement();
+                stmt.executeUpdate(commands[i]);
+            }
+            conn.commit();
+        } catch (SQLException e) {
+            try {
+                conn.rollback();
+            } catch (SQLException e1) {
+                log.error("Error during rollback", e);
+            }
+            throw new TilesTestRuntimeException("Error during execution of SQL commands", e);
+        } finally {
+            try {
+                if (conn != null) {
+                    conn.close();
+                }
+                if (stmt != null) {
+                    stmt.close();
+                }
+            } catch (SQLException e) {
+                log.error("Error during closing resources", e);
+            }
+        }
+    }
+}
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/init/TestTilesInitializer.java b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/init/TestTilesInitializer.java
new file mode 100644
index 000000000..3e5b0d5ee
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/init/TestTilesInitializer.java
@@ -0,0 +1,53 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.test.init;
+
+import javax.servlet.ServletContext;
+
+import org.apache.tiles.factory.AbstractTilesContainerFactory;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.servlet.wildcard.WildcardServletApplicationContext;
+import org.apache.tiles.startup.AbstractTilesInitializer;
+import org.apache.tiles.test.factory.TestTilesContainerFactory;
+
+/**
+ * Test Tiles initializer for Tiles initialization of the default container.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TestTilesInitializer extends AbstractTilesInitializer {
+
+    /** {@inheritDoc} */
+    @Override
+    protected AbstractTilesContainerFactory createContainerFactory(
+            ApplicationContext context) {
+        return new TestTilesContainerFactory();
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected ApplicationContext createTilesApplicationContext(
+            ApplicationContext preliminaryContext) {
+        return new WildcardServletApplicationContext(
+                (ServletContext) preliminaryContext.getContext());
+    }
+}
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/init/package.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/init/package.html
new file mode 100644
index 000000000..3617584c7
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/init/package.html
@@ -0,0 +1,30 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+    <title>Tiles test initialization.</title>
+</head>
+<body>
+Initialization classes used in the test web application.
+</body>
+</html>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/portlet/TestPortlet.java b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/portlet/TestPortlet.java
new file mode 100644
index 000000000..431b61c04
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/portlet/TestPortlet.java
@@ -0,0 +1,154 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.test.portlet;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import javax.portlet.ActionRequest;
+import javax.portlet.ActionResponse;
+import javax.portlet.GenericPortlet;
+import javax.portlet.PortletContext;
+import javax.portlet.PortletException;
+import javax.portlet.PortletRequestDispatcher;
+import javax.portlet.PortletSession;
+import javax.portlet.PortletURL;
+import javax.portlet.ProcessAction;
+import javax.portlet.RenderRequest;
+import javax.portlet.RenderResponse;
+
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.access.TilesAccess;
+import org.apache.tiles.request.Request;
+import org.apache.tiles.request.portlet.RenderPortletRequest;
+
+/**
+ * Test Portlet.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TestPortlet extends GenericPortlet {
+
+    /** {@inheritDoc} */
+    @Override
+    protected void doView(RenderRequest request, RenderResponse response)
+            throws PortletException, IOException {
+        PortletSession portletSession = request.getPortletSession();
+        String definition = (String) portletSession.getAttribute("definition");
+        if (definition != null) {
+            portletSession.removeAttribute("definition");
+            TilesContainer container = getCurrentContainer(request,
+                    getPortletContext());
+            Request currentRequest = new RenderPortletRequest(container
+                    .getApplicationContext(), getPortletContext(), request,
+                    response);
+            if (container.isValidDefinition(definition, currentRequest)) {
+                container.render(definition, currentRequest);
+                addBackLink(response);
+            } else {
+                PortletRequestDispatcher dispatcher = getPortletContext()
+                        .getRequestDispatcher(
+                                "/WEB-INF/jsp/nosuchdefinition.jsp");
+                dispatcher.forward(request, response);
+                addBackLink(response);
+            }
+        } else {
+            PortletRequestDispatcher dispatcher = getPortletContext()
+                    .getRequestDispatcher("/WEB-INF/jsp/index.jsp");
+            dispatcher.forward(request, response);
+        }
+    }
+
+
+    /**
+     * Puts the definition name in a session attribue.
+     *
+     * @param request The portlet request.
+     * @param response The portlet response.
+     */
+    @ProcessAction(name = "showDefinition")
+    public void showDefinition(ActionRequest request, ActionResponse response) {
+        request.getPortletSession().setAttribute("definition",
+                request.getParameter("definition"));
+    }
+
+    /**
+     * Adds a link to the response to go back.
+     *
+     * @param response The portlet response.
+     * @throws IOException If something goes wrong.
+     */
+    private void addBackLink(RenderResponse response) throws IOException {
+        PrintWriter writer = response.getWriter();
+        writer.append("<a href=\"");
+        PortletURL url = response.createRenderURL();
+        writer.append(url.toString());
+        writer.append("\"> Back to definition selection</a>");
+    }
+
+    /**
+     * Returns the current container that has been set, or the default one.
+     *
+     * @param request The request to use.
+     * @param context The portlet context to use.
+     * @return The current Tiles container to use in web pages.
+     * @since 2.1.0
+     */
+    private static TilesContainer getCurrentContainer(
+            javax.portlet.PortletRequest request, PortletContext context) {
+        TilesContainer container = (TilesContainer) request
+                .getAttribute(TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME);
+        if (container == null) {
+            container = getContainer(context);
+            request.setAttribute(TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME,
+                    container);
+        }
+
+        return container;
+    }
+
+    /**
+     * Returns a specific Tiles container.
+     *
+     * @param context The portlet context to use.
+     * @param key The key under which the container is stored. If null, the
+     * default container will be returned.
+     * @return The requested Tiles container.
+     * @since 2.1.2
+     */
+    private static TilesContainer getContainer(PortletContext context, String key) {
+        if (key == null) {
+            key = TilesAccess.CONTAINER_ATTRIBUTE;
+        }
+        return (TilesContainer) context.getAttribute(key);
+    }
+
+    /**
+     * Returns the default Tiles container.
+     *
+     * @param context The portlet context to use.
+     * @return The default Tiles container.
+     * @since 2.1.2
+     */
+    private static TilesContainer getContainer(PortletContext context) {
+        return getContainer(context, TilesAccess.CONTAINER_ATTRIBUTE);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/portlet/package.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/portlet/package.html
new file mode 100644
index 000000000..dad19081b
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/portlet/package.html
@@ -0,0 +1,30 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+    <title>Test portlets.</title>
+</head>
+<body>
+Test portlets for Tiles evaluation.
+</body>
+</html>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/preparer/AttributeViewPreparer.java b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/preparer/AttributeViewPreparer.java
new file mode 100644
index 000000000..01304ce36
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/preparer/AttributeViewPreparer.java
@@ -0,0 +1,42 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.test.preparer;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.AttributeContext;
+import org.apache.tiles.preparer.ViewPreparer;
+import org.apache.tiles.request.Request;
+
+/**
+ * A <code>ViewPreparer</code> that stores an attribute.
+ *
+ * @version $Rev$ $Date$
+ */
+public class AttributeViewPreparer implements ViewPreparer {
+
+    /** {@inheritDoc} */
+    public void execute(Request tilesContext,
+            AttributeContext attributeContext) {
+        attributeContext.putAttribute(
+            "body",
+            new Attribute("This is the value added by the AttributeViewPreparer"));
+    }
+}
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/preparer/RequestSettingViewPreparer.java b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/preparer/RequestSettingViewPreparer.java
new file mode 100644
index 000000000..9f9f19865
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/preparer/RequestSettingViewPreparer.java
@@ -0,0 +1,46 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.test.preparer;
+
+import java.util.Map;
+
+import org.apache.tiles.AttributeContext;
+import org.apache.tiles.preparer.ViewPreparer;
+import org.apache.tiles.request.Request;
+
+/**
+ * A simple test <code>ViewPreparer</code> to put a request attribute, that
+ * will be used with the EL evaluator.
+ *
+ * @version $Rev$ $Date$
+ */
+public class RequestSettingViewPreparer implements ViewPreparer {
+
+    /** {@inheritDoc} */
+    public void execute(Request tilesContext,
+            AttributeContext attributeContext) {
+        Map<String, Object> requestScope = tilesContext.getContext("request");
+        requestScope.put("body", "test.inner.definition");
+        requestScope.put("layout", "/layout.jsp");
+        requestScope.put("doNotShow", "DO NOT SHOW!!!");
+        requestScope.put("doNotShowBody", "${requestScope.doNotShow}");
+    }
+}
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/preparer/TestViewPreparer.java b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/preparer/TestViewPreparer.java
new file mode 100644
index 000000000..23f4f606a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/preparer/TestViewPreparer.java
@@ -0,0 +1,42 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.test.preparer;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.AttributeContext;
+import org.apache.tiles.preparer.ViewPreparer;
+import org.apache.tiles.request.Request;
+
+/**
+ * A simple test <code>ViewPreparer</code>.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TestViewPreparer implements ViewPreparer {
+
+    /** {@inheritDoc} */
+    public void execute(Request tilesContext,
+            AttributeContext attributeContext) {
+        attributeContext.putAttribute(
+            "body",
+            new Attribute("This is the value added by the ViewPreparer"));
+    }
+}
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/preparer/package.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/preparer/package.html
new file mode 100644
index 000000000..2732073d2
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/preparer/package.html
@@ -0,0 +1,30 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+    <title>Tiles preparer test package</title>
+</head>
+<body>
+Test classes to check preparer functionality.
+</body>
+</html>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/servlet/IncludingServlet.java b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/servlet/IncludingServlet.java
new file mode 100644
index 000000000..9dbdbb5a2
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/servlet/IncludingServlet.java
@@ -0,0 +1,72 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.test.servlet;
+
+import java.io.IOException;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * Sample servlet that includes a page specified by the <code>include</code>
+ * init parameter.
+ *
+ * @version $Rev$ $Date$
+ */
+public class IncludingServlet extends HttpServlet {
+
+    /**
+     * Init parameter value, that indicates the path to include.
+     */
+    private String include;
+
+    /**
+     * Initializes the servlet, reading the <code>include</code> init
+     * parameter.
+     *
+     * @param config The servlet configuration object to use.
+     * @throws ServletException Thrown by
+     * {@link HttpServlet#init(ServletConfig)}
+     */
+    @Override
+    public void init(ServletConfig config) throws ServletException {
+        super.init(config);
+
+        include = config.getInitParameter("include");
+    }
+
+    /**
+     * Processes the request, including the specified page.
+     *
+     * @param request The request object.
+     * @param response The response object.
+     * @throws ServletException Thrown by the {@link #include} method.
+     * @throws IOException Thrown by the {@link #include} method.
+     */
+    @Override
+    protected void doGet(HttpServletRequest request,
+            HttpServletResponse response) throws ServletException, IOException {
+        request.getRequestDispatcher(include).include(request, response);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/servlet/SelectLocaleServlet.java b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/servlet/SelectLocaleServlet.java
new file mode 100644
index 000000000..ed98c3f8f
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/servlet/SelectLocaleServlet.java
@@ -0,0 +1,109 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.test.servlet;
+
+import java.util.Locale;
+
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.access.TilesAccess;
+import org.apache.tiles.locale.impl.DefaultLocaleResolver;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.Request;
+import org.apache.tiles.request.servlet.ServletRequest;
+
+/**
+ * Servlet able to let a user choose a locale.
+ *
+ * @version $Rev$ $Date$
+ */
+public class SelectLocaleServlet extends HttpServlet {
+
+    /**
+     * The key of the container to use.
+     */
+    private String containerKey;
+
+    /**
+     * The name of the definition to render.
+     */
+    private String definitionName;
+
+    /** {@inheritDoc} */
+    @Override
+    public void init(ServletConfig config) throws ServletException {
+        super.init(config);
+        containerKey = config
+                .getInitParameter("org.apache.tiles.test.servlet.ServletConfig.CONTAINER_KEY");
+        definitionName = config
+                .getInitParameter("org.apache.tiles.test.servlet.ServletConfig.DEFINITION_NAME");
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected void doGet(HttpServletRequest request,
+            HttpServletResponse response) {
+        process(request, response);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected void doPost(HttpServletRequest request,
+            HttpServletResponse response) {
+        process(request, response);
+    }
+
+    /**
+     * Processes the request.
+     *
+     * @param request The request object.
+     * @param response The response object.
+     */
+    private void process(HttpServletRequest request,
+            HttpServletResponse response) {
+        String localeParameter = request.getParameter("locale");
+        HttpSession session = request.getSession();
+        Locale locale = null;
+        if (localeParameter != null && localeParameter.trim().length() > 0) {
+            String[] localeStrings = localeParameter.split("_");
+            if (localeStrings.length == 1) {
+                locale = new Locale(localeStrings[0]);
+            } else if (localeStrings.length == 2) {
+                locale = new Locale(localeStrings[0], localeStrings[1]);
+            } else if (localeStrings.length > 2) {
+                locale = new Locale(localeStrings[0], localeStrings[1], localeStrings[2]);
+            }
+        }
+        session.setAttribute(DefaultLocaleResolver.LOCALE_KEY, locale);
+        ApplicationContext applicationContext = org.apache.tiles.request.servlet.ServletUtil
+                .getApplicationContext(getServletContext());
+        Request currentRequest = new ServletRequest(applicationContext, request, response);
+        TilesAccess.setCurrentContainer(currentRequest, containerKey);
+        TilesContainer container = TilesAccess.getCurrentContainer(currentRequest);
+        container.render(definitionName, currentRequest);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/servlet/package.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/servlet/package.html
new file mode 100644
index 000000000..ecdf30f01
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/servlet/package.html
@@ -0,0 +1,30 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+    <title>Tiles servlet test package</title>
+</head>
+<body>
+Test servlet classes.
+</body>
+</html>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/velocity/ExceptionTool.java b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/velocity/ExceptionTool.java
new file mode 100644
index 000000000..5434cf85a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/velocity/ExceptionTool.java
@@ -0,0 +1,38 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.test.velocity;
+
+/**
+ * Tool to generate exceptions.
+ *
+ * @version $Rev$ $Date$
+ */
+public class ExceptionTool {
+
+    /**
+     * Throws an exception.
+     *
+     * @return Nothing.
+     */
+    public String throwRuntimeException() {
+        throw new RuntimeException("It is an exception!");
+    }
+}
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/velocity/package.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/velocity/package.html
new file mode 100644
index 000000000..b0de056aa
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/java/org/apache/tiles/test/velocity/package.html
@@ -0,0 +1,30 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+    <title>Tiles Velocity test package</title>
+</head>
+<body>
+Velocity tools and utilities.
+</body>
+</html>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/resources/LICENSE.txt b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/resources/LICENSE.txt
new file mode 100644
index 000000000..d64569567
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/resources/LICENSE.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/resources/META-INF/MANIFEST.MF b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/resources/META-INF/MANIFEST.MF
new file mode 100644
index 000000000..b479d32cd
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/resources/META-INF/MANIFEST.MF
@@ -0,0 +1,14 @@
+Manifest-Version: 1.0
+Archiver-Version: Plexus Archiver
+Created-By: Apache Maven
+Built-By: antonio
+Build-Jdk: 1.6.0_16
+Specification-Title: Tiles - Apps - Test
+Specification-Version: 2.2.1-SNAPSHOT
+Specification-Vendor: Apache Software Foundation
+Implementation-Title: Tiles - Apps - Test
+Implementation-Version: 2.2.1-SNAPSHOT
+Implementation-Vendor-Id: org.apache.tiles
+Implementation-Vendor: Apache Software Foundation
+Tiles-Initializer: org.apache.tiles.test.init.TestTilesInitializer
+
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/resources/NOTICE.txt b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/resources/NOTICE.txt
new file mode 100644
index 000000000..aef6d99cc
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/resources/NOTICE.txt
@@ -0,0 +1,6 @@
+   Apache Tiles
+   Copyright 1999-2009 The Apache Software Foundation
+
+   This product includes software developed at
+   The Apache Software Foundation (http://www.apache.org/).
+   Spring (http://www.springframework.org/).
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/resources/org/apache/tiles/classpath-defs.xml b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/resources/org/apache/tiles/classpath-defs.xml
new file mode 100644
index 000000000..459aa392f
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/resources/org/apache/tiles/classpath-defs.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+<!DOCTYPE tiles-definitions PUBLIC
+    "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
+    "http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
+
+<!-- Definitions for Tiles documentation   -->
+
+<tiles-definitions>
+    <definition name="classpath.definition" template="/layout.jsp">
+        <put-attribute name="title" value="This is the title."/>
+        <put-attribute name="header" value="/header.jsp"/>
+        <put-attribute name="body" value="/classpath.jsp"/>
+    </definition>
+</tiles-definitions>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/resources/org/apache/tiles/freemarker-classpath-defs.xml b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/resources/org/apache/tiles/freemarker-classpath-defs.xml
new file mode 100644
index 000000000..f63b9102d
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/resources/org/apache/tiles/freemarker-classpath-defs.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+<!DOCTYPE tiles-definitions PUBLIC
+    "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
+    "http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
+
+<!-- Definitions for Tiles documentation   -->
+
+<tiles-definitions>
+    <definition name="freemarker.classpath.definition" template="/freemarker/layout.ftl">
+        <put-attribute name="title" value="This is the title."/>
+        <put-attribute name="header" value="/freemarker/header.ftl"/>
+        <put-attribute name="body" value="/freemarker/classpath.ftl"/>
+    </definition>
+</tiles-definitions>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/resources/org/apache/tiles/test/db/schema.sql b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/resources/org/apache/tiles/test/db/schema.sql
new file mode 100644
index 000000000..d79143e9e
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/resources/org/apache/tiles/test/db/schema.sql
@@ -0,0 +1,146 @@
+
+CREATE TABLE public.Definition (
+                id NUMERIC(12,0) NOT NULL,
+                name VARCHAR(255) NOT NULL,
+                preparer VARCHAR(1000) NULL,
+                template VARCHAR(1000) NULL,
+                Customization_id NUMERIC(12,0) NOT NULL,
+                parent_name VARCHAR(255) NULL,
+                CONSTRAINT Definition_pk PRIMARY KEY (id)
+);
+
+CREATE INDEX public.Definition_idx
+ ON public.Definition
+ ( name ASC );
+
+CREATE TABLE public.Attribute (
+                id NUMERIC(12,0) NOT NULL,
+                name VARCHAR(255) NOT NULL,
+                type VARCHAR(255) NULL,
+                value VARCHAR(1000) NOT NULL,
+                cascade_attribute BOOLEAN NOT NULL,
+                Definition_id NUMERIC(12,0) NULL,
+                Parent_id NUMERIC(12,0) NULL,
+                CONSTRAINT Attribute_pk PRIMARY KEY (id)
+);
+
+CREATE TABLE public.Role (
+                id NUMERIC(12,0) NOT NULL,
+                name VARCHAR(255) NOT NULL,
+                CONSTRAINT Role_pk PRIMARY KEY (id)
+);
+
+CREATE INDEX public.Role_idx
+ ON public.Role
+ ( name ASC );
+
+CREATE TABLE public.Customization (
+                id NUMERIC(12,0) NOT NULL,
+                Parent_id NUMERIC(12,0) NULL,
+                name VARCHAR(255) NOT NULL,
+                CONSTRAINT Customization_pk PRIMARY KEY (id)
+);
+
+CREATE INDEX public.Customization_idx
+ ON public.Customization
+ ( name ASC );
+
+CREATE INDEX public.Customization_idx1
+ ON public.Customization
+ ( name ASC );
+
+CREATE TABLE public.Visible_for (
+                Definition_id NUMERIC(12,0) NOT NULL,
+                Role_id NUMERIC(12,0) NOT NULL,
+                CONSTRAINT Visible_for_pk PRIMARY KEY (Definition_id, Role_id)
+);
+
+CREATE TABLE public.Attribute_visible_for (
+                Attribute_id NUMERIC(12,0) NOT NULL,
+                Role_id NUMERIC(12,0) NOT NULL,
+                CONSTRAINT Attribute_visible_for_pk PRIMARY KEY (Attribute_id, Role_id)
+);
+
+
+ALTER TABLE public.Attribute ADD CONSTRAINT Definition_Attribute_fk
+FOREIGN KEY (Definition_id)
+REFERENCES public.Definition (id)
+;
+
+
+ALTER TABLE public.Visible_for ADD CONSTRAINT Definition_Visible_for_fk
+FOREIGN KEY (Definition_id)
+REFERENCES public.Definition (id)
+;
+
+
+ALTER TABLE public.Attribute ADD CONSTRAINT Attribute_Attribute_fk
+FOREIGN KEY (Parent_id)
+REFERENCES public.Attribute (id)
+;
+
+
+ALTER TABLE public.Attribute_visible_for ADD CONSTRAINT Attribute_Attribute_visible_for_fk
+FOREIGN KEY (Attribute_id)
+REFERENCES public.Attribute (id)
+;
+
+
+ALTER TABLE public.Visible_for ADD CONSTRAINT Role_Visible_for_fk
+FOREIGN KEY (Role_id)
+REFERENCES public.Role (id)
+;
+
+
+ALTER TABLE public.Attribute_visible_for ADD CONSTRAINT Role_Attribute_visible_for_fk
+FOREIGN KEY (Role_id)
+REFERENCES public.Role (id)
+;
+
+
+ALTER TABLE public.Definition ADD CONSTRAINT Customization_Definition_fk
+FOREIGN KEY (Customization_id)
+REFERENCES public.Customization (id)
+;
+
+
+ALTER TABLE public.Customization ADD CONSTRAINT Customization_Customization_fk
+FOREIGN KEY (Parent_id)
+REFERENCES public.Customization (id)
+;
+
+INSERT INTO "PUBLIC"."CUSTOMIZATION" (ID,PARENT_ID,NAME) VALUES (0,null,'');
+INSERT INTO "PUBLIC"."CUSTOMIZATION" (ID,PARENT_ID,NAME) VALUES (1,0,'en');
+INSERT INTO "PUBLIC"."CUSTOMIZATION" (ID,PARENT_ID,NAME) VALUES (2,1,'en_GB');
+INSERT INTO "PUBLIC"."CUSTOMIZATION" (ID,PARENT_ID,NAME) VALUES (3,1,'en_US');
+INSERT INTO "PUBLIC"."CUSTOMIZATION" (ID,PARENT_ID,NAME) VALUES (4,0,'fr');
+INSERT INTO "PUBLIC"."CUSTOMIZATION" (ID,PARENT_ID,NAME) VALUES (5,0,'it');
+
+INSERT INTO "PUBLIC"."DEFINITION" (ID,PARENT_NAME,NAME,PREPARER,TEMPLATE,CUSTOMIZATION_ID) VALUES (0,null,'test.localized.definition',null,'/layout.jsp',0);
+INSERT INTO "PUBLIC"."DEFINITION" (ID,PARENT_NAME,NAME,PREPARER,TEMPLATE,CUSTOMIZATION_ID) VALUES (2,null,'test.localized.definition',null,'/layout.jsp',2);
+INSERT INTO "PUBLIC"."DEFINITION" (ID,PARENT_NAME,NAME,PREPARER,TEMPLATE,CUSTOMIZATION_ID) VALUES (3,null,'test.localized.definition',null,'/layout.jsp',3);
+INSERT INTO "PUBLIC"."DEFINITION" (ID,PARENT_NAME,NAME,PREPARER,TEMPLATE,CUSTOMIZATION_ID) VALUES (4,null,'test.localized.definition',null,'/layout.jsp',4);
+INSERT INTO "PUBLIC"."DEFINITION" (ID,PARENT_NAME,NAME,PREPARER,TEMPLATE,CUSTOMIZATION_ID) VALUES (5,null,'test.localized.definition',null,'/layout.jsp',5);
+
+INSERT INTO "PUBLIC"."ATTRIBUTE" (ID,NAME,TYPE,VALUE,CASCADE_ATTRIBUTE,DEFINITION_ID,PARENT_ID) VALUES (0,'title',null,'Default locale',0,0,null);
+INSERT INTO "PUBLIC"."ATTRIBUTE" (ID,NAME,TYPE,VALUE,CASCADE_ATTRIBUTE,DEFINITION_ID,PARENT_ID) VALUES (1,'header',null,'/header.jsp',0,0,null);
+INSERT INTO "PUBLIC"."ATTRIBUTE" (ID,NAME,TYPE,VALUE,CASCADE_ATTRIBUTE,DEFINITION_ID,PARENT_ID) VALUES (2,'body',null,'/defaultlocale_db.jsp',0,0,null);
+INSERT INTO "PUBLIC"."ATTRIBUTE" (ID,NAME,TYPE,VALUE,CASCADE_ATTRIBUTE,DEFINITION_ID,PARENT_ID) VALUES (3,'title',null,'British English locale',0,2,null);
+INSERT INTO "PUBLIC"."ATTRIBUTE" (ID,NAME,TYPE,VALUE,CASCADE_ATTRIBUTE,DEFINITION_ID,PARENT_ID) VALUES (4,'header',null,'/header.jsp',0,2,null);
+INSERT INTO "PUBLIC"."ATTRIBUTE" (ID,NAME,TYPE,VALUE,CASCADE_ATTRIBUTE,DEFINITION_ID,PARENT_ID) VALUES (5,'body',null,'/defaultlocale_db.jsp',0,2,null);
+INSERT INTO "PUBLIC"."ATTRIBUTE" (ID,NAME,TYPE,VALUE,CASCADE_ATTRIBUTE,DEFINITION_ID,PARENT_ID) VALUES (6,'title',null,'American English locale',0,3,null);
+INSERT INTO "PUBLIC"."ATTRIBUTE" (ID,NAME,TYPE,VALUE,CASCADE_ATTRIBUTE,DEFINITION_ID,PARENT_ID) VALUES (7,'header',null,'/header.jsp',0,3,null);
+INSERT INTO "PUBLIC"."ATTRIBUTE" (ID,NAME,TYPE,VALUE,CASCADE_ATTRIBUTE,DEFINITION_ID,PARENT_ID) VALUES (8,'body',null,'/defaultlocale_db.jsp',0,3,null);
+INSERT INTO "PUBLIC"."ATTRIBUTE" (ID,NAME,TYPE,VALUE,CASCADE_ATTRIBUTE,DEFINITION_ID,PARENT_ID) VALUES (9,'title',null,'French locale',0,4,null);
+INSERT INTO "PUBLIC"."ATTRIBUTE" (ID,NAME,TYPE,VALUE,CASCADE_ATTRIBUTE,DEFINITION_ID,PARENT_ID) VALUES (10,'header',null,'/header.jsp',0,4,null);
+INSERT INTO "PUBLIC"."ATTRIBUTE" (ID,NAME,TYPE,VALUE,CASCADE_ATTRIBUTE,DEFINITION_ID,PARENT_ID) VALUES (11,'body',null,'/defaultlocale_db.jsp',0,4,null);
+INSERT INTO "PUBLIC"."ATTRIBUTE" (ID,NAME,TYPE,VALUE,CASCADE_ATTRIBUTE,DEFINITION_ID,PARENT_ID) VALUES (12,'title',null,'Italian locale',0,5,null);
+INSERT INTO "PUBLIC"."ATTRIBUTE" (ID,NAME,TYPE,VALUE,CASCADE_ATTRIBUTE,DEFINITION_ID,PARENT_ID) VALUES (13,'header',null,'/header.jsp',0,5,null);
+INSERT INTO "PUBLIC"."ATTRIBUTE" (ID,NAME,TYPE,VALUE,CASCADE_ATTRIBUTE,DEFINITION_ID,PARENT_ID) VALUES (14,'body',null,'/defaultlocale_db.jsp',0,5,null);
+
+INSERT INTO "PUBLIC"."DEFINITION" (ID,PARENT_NAME,NAME,PREPARER,TEMPLATE,CUSTOMIZATION_ID) VALUES (6,null,'test.definition',null,'/layout.jsp',0);
+INSERT INTO "PUBLIC"."ATTRIBUTE" (ID,NAME,TYPE,VALUE,CASCADE_ATTRIBUTE,DEFINITION_ID,PARENT_ID) VALUES (15,'title',null,'This is the title.',0,6,null);
+INSERT INTO "PUBLIC"."ATTRIBUTE" (ID,NAME,TYPE,VALUE,CASCADE_ATTRIBUTE,DEFINITION_ID,PARENT_ID) VALUES (16,'header',null,'/header.jsp',0,6,null);
+INSERT INTO "PUBLIC"."ATTRIBUTE" (ID,NAME,TYPE,VALUE,CASCADE_ATTRIBUTE,DEFINITION_ID,PARENT_ID) VALUES (17,'body',null,'/body.jsp',0,6,null);
+INSERT INTO "PUBLIC"."DEFINITION" (ID,PARENT_NAME,NAME,PREPARER,TEMPLATE,CUSTOMIZATION_ID) VALUES (7,'test.definition','test.definition.extended',null,null,0);
+INSERT INTO "PUBLIC"."ATTRIBUTE" (ID,NAME,TYPE,VALUE,CASCADE_ATTRIBUTE,DEFINITION_ID,PARENT_ID) VALUES (18,'title',null,'This is an extended definition.',0,7,null);
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/resources/org/apache/tiles/velocity-classpath-defs.xml b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/resources/org/apache/tiles/velocity-classpath-defs.xml
new file mode 100644
index 000000000..aba67d5a8
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/resources/org/apache/tiles/velocity-classpath-defs.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+<!DOCTYPE tiles-definitions PUBLIC
+    "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
+    "http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
+
+<!-- Definitions for Tiles documentation   -->
+
+<tiles-definitions>
+    <definition name="velocity.classpath.definition" template="/velocity/layout.vm">
+        <put-attribute name="title" value="This is the title."/>
+        <put-attribute name="header" value="/velocity/header.vm"/>
+        <put-attribute name="body" value="/velocity/classpath.vm"/>
+    </definition>
+</tiles-definitions>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/VM_global_library.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/VM_global_library.vm
new file mode 100644
index 000000000..7e8277de0
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/VM_global_library.vm
@@ -0,0 +1,60 @@
+## 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.
+
+## Display all queued Struts errors
+#macro (errorMarkup)
+    #if ($errors.exist() )
+        <ul>
+        #foreach ($e in $errors.all )
+            $e
+        #end
+        </ul>
+    #end
+#end
+
+## Display all queued Struts errors for a particular property
+#macro (errorMarkupForProperty $property)
+    #if ($errors.exist($property) )
+        <ul>
+        #foreach ($er in $errors.get($property))
+            $er
+        #end
+        </ul>
+    #end
+#end
+
+## Display all queued Struts errors
+#macro (messageMarkup)
+    #if ($messages.exist() )
+        <ul>
+        #foreach ($m in $messages.all )
+            $m
+        #end
+        </ul>
+    #end
+#end
+
+## Display all queued Struts action messages for a particular property
+#macro (messageMarkupForProperty $property)
+    #if ($messages.exist($property) )
+        <ul>
+        #foreach ($m in $messages.get($property))
+            $m
+        #end
+        </ul>
+    #end
+#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/freemarker/tiles-defs-1.1.xml b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/freemarker/tiles-defs-1.1.xml
new file mode 100644
index 000000000..d32c6f144
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/freemarker/tiles-defs-1.1.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 1.1//EN"
+       "http://struts.apache.org/dtds/tiles-config_1_1.dtd">
+
+<!-- Definitions for Tiles documentation   -->
+
+<tiles-definitions>
+
+  <definition name="freemarker.test.definition.old_format" template="/freemarker/layout.ftl">
+      <put name="title"  value="This is a definition configured in 1.1 format."/>
+      <put name="header" value="/freemarker/header.ftl"/>
+      <put name="body"   value="/freemarker/body.ftl"/>
+  </definition>
+
+</tiles-definitions>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/freemarker/tiles-defs.xml b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/freemarker/tiles-defs.xml
new file mode 100644
index 000000000..6aa3095c3
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/freemarker/tiles-defs.xml
@@ -0,0 +1,252 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 2.1//EN"
+       "http://tiles.apache.org/dtds/tiles-config_2_1.dtd">
+
+<!-- Definitions for Tiles documentation   -->
+
+<tiles-definitions>
+
+  <!-- =======================================================  -->
+  <!-- Master definition  									-->
+  <!-- =======================================================  -->
+
+  <!-- Doc index page description  -->
+  <definition name="freemarker.test.inner.definition" template="/freemarker/layout.ftl" templateType="freemarker">
+      <put-attribute name="title"  value="This is a configured inner definition."/>
+      <put-attribute name="header" value="/freemarker/header.ftl" type="freemarker" />
+      <put-attribute name="body"   value="/freemarker/body.ftl" type="freemarker" />
+  </definition>
+
+  <definition name="freemarker.test.definition" template="/freemarker/layout.ftl" templateType="freemarker">
+      <put-attribute name="title"  value="This is the title."/>
+      <put-attribute name="header" value="/freemarker/header.ftl" type="freemarker" />
+      <put-attribute name="body"   value="/freemarker/body.ftl" type="freemarker" />
+  </definition>
+
+  <definition name="freemarker.test.definition.ignore" template="/freemarker/layout_ignore.ftl" templateType="freemarker">
+      <put-attribute name="title"  value="This is the title."/>
+      <put-attribute name="body"   value="/freemarker/body.ftl" type="freemarker" />
+  </definition>
+
+  <definition name="freemarker.test.definition.freemarker" template="/freemarker/layout.ftl" templateType="freemarker">
+      <put-attribute name="title"  value="This is the title."/>
+      <put-attribute name="header" value="/freemarker/header.ftl" type="freemarker" />
+      <put-attribute name="body"   value="/freemarker/body.ftl" type="freemarker" />
+  </definition>
+
+  <definition name="freemarker.test.definition.flush" template="/freemarker/layout_flush.ftl" templateType="freemarker">
+      <put-attribute name="title"  value="This is the title."/>
+      <put-attribute name="header" value="/freemarker/header.ftl" type="freemarker" />
+      <put-attribute name="body"   value="/freemarker/body.ftl" type="freemarker" />
+  </definition>
+
+  <definition name="freemarker.test.definition.exception" template="/freemarker/layout.ftl" templateType="freemarker">
+      <put-attribute name="title"  value="This is the title."/>
+      <put-attribute name="header" value="/freemarker/exception.ftl" type="freemarker" />
+      <put-attribute name="body"   value="/freemarker/body.ftl" type="freemarker" />
+  </definition>
+
+  <definition name="freemarker.test.composite.definition" template="/freemarker/layout.ftl" templateType="freemarker">
+      <put-attribute name="title"  value="This is a configured composite definition."/>
+      <put-attribute name="header" value="/freemarker/header.ftl" type="freemarker" />
+      <put-attribute name="body"   value="test.inner.definition"/>
+  </definition>
+
+  <definition name="freemarker.test.putAttributes" template="/freemarker/putattributeslayout.ftl" templateType="freemarker">
+    <put-attribute name="stringTest" value="This is a string" type="string" />
+    <put-list-attribute name="list">
+      <add-attribute value="valueOne" type="string" />
+      <add-attribute value="valueTwo" type="string" />
+      <add-attribute value="valueThree" type="string" />
+    </put-list-attribute>
+  </definition>
+
+  <definition name="freemarker.test.putAttributes.inherit" extends="freemarker.test.putAttributes">
+    <put-list-attribute name="list" inherit="true">
+      <add-attribute value="valueFour" type="string" />
+    </put-list-attribute>
+  </definition>
+
+  <definition name="freemarker.test.putAllAttributes" template="/freemarker/putallattributeslayout.ftl" templateType="freemarker">
+    <put-attribute name="one" value="There should be three more strings" type="string" />
+    <put-attribute name="two" value="One" type="string" />
+    <put-attribute name="three" value="Two" type="string" />
+    <put-attribute name="four" value="Three" type="string" />
+  </definition>
+
+  <definition name="freemarker.preparer.definition" template="/freemarker/layout.ftl" templateType="freemarker">
+      <put-attribute name="title"  value="This is the title."/>
+      <put-attribute name="header" value="/freemarker/header.ftl" type="freemarker" />
+  </definition>
+
+    <definition name="freemarker.testdispatchservlet" extends="test.definition"/>
+
+  <definition name="freemarker.preparer.definition.configured" extends="preparer.definition" preparer="org.apache.tiles.test.preparer.TestViewPreparer" />
+
+  <definition name="freemarker.test.localized.definition" template="/freemarker/layout.ftl" templateType="freemarker">
+      <put-attribute name="title" value="Default locale" />
+      <put-attribute name="header" value="/freemarker/header.ftl" type="freemarker" />
+      <put-attribute name="body" value="/freemarker/defaultlocale.ftl" type="freemarker" />
+  </definition>
+
+  <definition name="freemarker.test.definition.appears" extends="test.definition">
+      <put-attribute name="title"  value="This definition appears."/>
+  </definition>
+
+  <definition name="freemarker.test.definition.does_not_appear" extends="test.definition">
+      <put-attribute name="title"  value="This definition does
+       not appear."/>
+  </definition>
+
+  <definition name="freemarker.test.definition.appears.configured"
+    extends="test.definition.appears" role="goodrole" />
+
+  <definition name="freemarker.test.definition.does_not_appear.configured"
+    extends="test.definition.does_not_appear" role="badrole" />
+
+  <definition name="freemarker.test.definition.roles" template="/freemarker/layout.ftl" templateType="freemarker">
+      <put-attribute name="title"  value="This is the title."/>
+      <put-attribute name="header" value="/freemarker/header.ftl" role="goodrole" />
+      <put-attribute name="body"   value="/freemarker/body.ftl" role="badrole" />
+  </definition>
+
+  <definition name="freemarker.test.definition.roles.tags" template="/freemarker/layout_roles.ftl" templateType="freemarker">
+      <put-attribute name="title"  value="This is the title."/>
+      <put-attribute name="header" value="/freemarker/header.ftl" type="freemarker" />
+      <put-attribute name="body"   value="/freemarker/body.ftl" type="freemarker" />
+  </definition>
+
+  <!-- Tests for cascaded attributes -->
+  <definition name="freemarker.test.overridden.cascaded.definition" template="/freemarker/layout.ftl" templateType="freemarker">
+      <put-attribute name="title"  value="This is the title." cascade="true" />
+      <put-attribute name="header" value="/freemarker/alternate-header.ftl" cascade="true"/>
+      <put-attribute name="body"   value="test.inner.definition"/>
+  </definition>
+
+  <definition name="freemarker.test.inner.cascadable.definition" template="/freemarker/layout.ftl" templateType="freemarker">
+      <put-attribute name="body"   value="/freemarker/body.ftl" type="freemarker" />
+  </definition>
+
+  <definition name="freemarker.test.cascaded.definition" template="/freemarker/layout.ftl" templateType="freemarker">
+      <put-attribute name="title"  value="This is the title." cascade="true" />
+      <put-attribute name="header" value="/freemarker/header.ftl" cascade="true"/>
+      <put-attribute name="body"   value="test.inner.cascadable.definition"/>
+  </definition>
+
+  <definition name="freemarker.test.cascaded.template.definition" template="/freemarker/layout.ftl" templateType="freemarker">
+      <put-attribute name="title"  value="This is the title." cascade="true" />
+      <put-attribute name="header" value="/freemarker/header.ftl" cascade="true"/>
+      <put-attribute name="body"   value="/freemarker/layout_nobody.ftl" type="freemarker" />
+  </definition>
+
+  <definition name="freemarker.test.cascaded.list.definition" template="/freemarker/layout.ftl" templateType="freemarker">
+      <put-attribute name="title"  value="This is the title." cascade="true" />
+      <put-attribute name="header" value="/freemarker/header.ftl" cascade="true"/>
+      <put-attribute name="body"   value="/freemarker/putattributeslayout.ftl" type="freemarker" />
+      <put-attribute name="stringTest" value="This is a string" type="string" cascade="true" />
+      <put-list-attribute name="list" cascade="true">
+        <add-attribute value="valueOne" type="string" />
+        <add-attribute value="valueTwo" type="string" />
+        <add-attribute value="valueThree" type="string" />
+      </put-list-attribute>
+  </definition>
+
+  <definition name="freemarker.test.reversed.definition" template="/freemarker/layout_alt_title.ftl" templateType="freemarker">
+      <put-attribute name="title"  value="This is the title." type="reversed"/>
+      <put-attribute name="header" value="/freemarker/header.ftl" type="freemarker" />
+      <put-attribute name="body"   value="/freemarker/body.ftl" type="freemarker" />
+  </definition>
+
+  <definition name="freemarker.test.nesting.definitions" template="/freemarker/layout.ftl" templateType="freemarker">
+      <put-attribute name="title"  value="This is the title."/>
+      <put-attribute name="header" value="/freemarker/header.ftl" type="freemarker" />
+      <put-attribute name="body">
+          <definition template="/freemarker/layout.ftl" templateType="freemarker">
+              <put-attribute name="title"  value="This is a nested definition."/>
+              <put-attribute name="header" value="/freemarker/header.ftl" type="freemarker" />
+              <put-attribute name="body"   value="/freemarker/body.ftl" type="freemarker" />
+          </definition>
+      </put-attribute>
+  </definition>
+
+  <definition name="freemarker.test.nesting.list.definitions" template="/freemarker/layout_list.ftl" templateType="freemarker">
+      <put-attribute name="title"  value="This is the title."/>
+      <put-attribute name="header" value="/freemarker/header.ftl" type="freemarker" />
+      <put-list-attribute name="list">
+          <add-attribute>
+              <definition template="/freemarker/layout.ftl" templateType="freemarker">
+                  <put-attribute name="title"  value="This is a nested definition."/>
+                  <put-attribute name="header" value="/freemarker/header.ftl" type="freemarker" />
+                  <put-attribute name="body"   value="/freemarker/body.ftl" type="freemarker" />
+              </definition>
+          </add-attribute>
+      </put-list-attribute>
+  </definition>
+
+  <definition name="freemarker.test.composite.el.definition" templateExpression="${layout}"
+        preparer="org.apache.tiles.test.preparer.RequestSettingViewPreparer">
+      <put-attribute name="title"  value="This is a configured composite definition."/>
+      <put-attribute name="header" value="/freemarker/header.ftl" type="freemarker" />
+      <put-attribute name="body"   expression="${requestScope.body}"/>
+  </definition>
+
+  <definition name="freemarker.test.composite.mvel.definition" templateExpression="MVEL:layout"
+        preparer="org.apache.tiles.test.preparer.RequestSettingViewPreparer">
+      <put-attribute name="title"  value="This is a configured composite definition."/>
+      <put-attribute name="header" value="/freemarker/header.ftl" type="freemarker" />
+      <put-attribute name="body"   expression="MVEL:requestScope.body"/>
+  </definition>
+
+  <definition name="freemarker.test.composite.ognl.definition" templateExpression="OGNL:layout"
+        preparer="org.apache.tiles.test.preparer.RequestSettingViewPreparer">
+      <put-attribute name="title"  value="This is a configured composite definition."/>
+      <put-attribute name="header" value="/freemarker/header.ftl" type="freemarker" />
+      <put-attribute name="body"   expression="OGNL:requestScope.body"/>
+  </definition>
+
+  <definition name="freemarker.test.composite.el.doNotShow.definition" templateExpression="${layout}"
+        preparer="org.apache.tiles.test.preparer.RequestSettingViewPreparer">
+      <put-attribute name="title"  value="This is a configured definition."/>
+      <put-attribute name="header" value="/freemarker/header.ftl" type="freemarker" />
+      <put-attribute name="body"   expression="${requestScope.doNotShowBody}"/>
+  </definition>
+
+  <definition name="freemarker.test.definition.attribute.preparer" template="/freemarker/layout_preparer.ftl" templateType="freemarker">
+      <put-attribute name="title"  value="This is the title."/>
+      <put-attribute name="header" value="/freemarker/header.ftl" type="freemarker" />
+  </definition>
+
+  <definition name="freemarker.test.openbody.definition" template="/freemarker/layout_closebody.ftl" templateType="freemarker">
+      <put-attribute name="title"  value="This is the title."/>
+      <put-attribute name="header" value="/freemarker/header.ftl" type="freemarker" />
+      <put-attribute name="body"   value="/freemarker/layout.ftl" type="freemarker" />
+  </definition>
+
+  <definition name="freemarker.test.defaultvalues.definition" template="/freemarker/layout_default.ftl" templateType="freemarker">
+      <put-attribute name="title"  value="This is the title."/>
+  </definition>
+</tiles-definitions>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/freemarker/tiles-defs_en_GB.xml b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/freemarker/tiles-defs_en_GB.xml
new file mode 100644
index 000000000..7f9543c1e
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/freemarker/tiles-defs_en_GB.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
+       "http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
+
+<!-- Definitions for Tiles documentation   -->
+
+<tiles-definitions>
+  <definition name="freemarker.test.localized.definition" template="/freemarker/layout.ftl">
+      <put-attribute name="title" value="British English locale" />
+      <put-attribute name="header" value="/freemarker/header.ftl" />
+      <put-attribute name="body" value="/freemarker/defaultlocale.ftl" />
+  </definition>
+
+</tiles-definitions>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/freemarker/tiles-defs_en_US.xml b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/freemarker/tiles-defs_en_US.xml
new file mode 100644
index 000000000..aa15c326a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/freemarker/tiles-defs_en_US.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
+       "http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
+
+<!-- Definitions for Tiles documentation   -->
+
+<tiles-definitions>
+  <definition name="freemarker.test.localized.definition" template="/freemarker/layout.ftl">
+      <put-attribute name="title" value="American English locale" />
+      <put-attribute name="header" value="/freemarker/header.ftl" />
+      <put-attribute name="body" value="/freemarker/defaultlocale.ftl" />
+  </definition>
+
+</tiles-definitions>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/freemarker/tiles-defs_fr.xml b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/freemarker/tiles-defs_fr.xml
new file mode 100644
index 000000000..5eb394ece
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/freemarker/tiles-defs_fr.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
+       "http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
+
+<!-- Definitions for Tiles documentation   -->
+
+<tiles-definitions>
+  <definition name="freemarker.test.localized.definition" template="/freemarker/layout.ftl">
+      <put-attribute name="title" value="French locale" />
+      <put-attribute name="header" value="/freemarker/header.ftl" />
+      <put-attribute name="body" value="/freemarker/defaultlocale.ftl" />
+  </definition>
+
+</tiles-definitions>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/freemarker/tiles-defs_it.xml b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/freemarker/tiles-defs_it.xml
new file mode 100644
index 000000000..79b0c6977
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/freemarker/tiles-defs_it.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
+       "http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
+
+<!-- Definitions for Tiles documentation   -->
+
+<tiles-definitions>
+  <definition name="freemarker.test.localized.definition" template="/freemarker/layout.ftl">
+      <put-attribute name="title" value="Italian locale" />
+      <put-attribute name="header" value="/freemarker/header.ftl" />
+      <put-attribute name="body" value="/freemarker/defaultlocale.ftl" />
+  </definition>
+
+</tiles-definitions>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/freemarker/tiles-defs_with_undescore.xml b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/freemarker/tiles-defs_with_undescore.xml
new file mode 100644
index 000000000..5acce5ef8
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/freemarker/tiles-defs_with_undescore.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
+       "http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
+
+<!-- Definitions for Tiles documentation   -->
+
+<tiles-definitions>
+  <definition name="freemarker.test.non.localized.definition" template="/freemarker/layout.ftl">
+      <put-attribute name="title" value="Non localized definition" />
+      <put-attribute name="header" value="/freemarker/header.ftl" />
+      <put-attribute name="body" value="/freemarker/body.ftl" />
+  </definition>
+
+</tiles-definitions>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/jsp/index.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/jsp/index.jsp
new file mode 100644
index 000000000..3f3f0ae2e
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/jsp/index.jsp
@@ -0,0 +1,43 @@
+<%@ page language="java" contentType="text/html; charset=UTF-8"
+    pageEncoding="UTF-8"%>
+<%@taglib prefix="portlet" uri="http://java.sun.com/portlet_2_0" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<portlet:defineObjects/>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Insert title here</title>
+</head>
+<body>
+<p>Type a definition name to render it.</p>
+<form action="<portlet:actionURL name='showDefinition' />" method="post">
+	<label for="definitionName">Definition name:</label><input id="definitionName" type="text" name="definition" />
+	<input type="submit" value="Render" />
+</form>
+
+
+</body>
+</html>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/jsp/nosuchdefinition.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/jsp/nosuchdefinition.jsp
new file mode 100644
index 000000000..8f6490fc3
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/jsp/nosuchdefinition.jsp
@@ -0,0 +1,35 @@
+<%@ page language="java" contentType="text/html; charset=UTF-8"
+    pageEncoding="UTF-8"%>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Insert title here</title>
+</head>
+<body>
+No definition here!
+</body>
+</html>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/portlet.xml b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/portlet.xml
new file mode 100644
index 000000000..cfc28d807
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/portlet.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<portlet-app
+  xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd"
+  version="2.0">
+
+  <portlet>
+    <portlet-name>TestPortlet</portlet-name>
+    <display-name>TestPortlet</display-name>
+    <portlet-class>
+      org.apache.tiles.test.portlet.TestPortlet
+    </portlet-class>
+    <supports>
+      <mime-type>text/html</mime-type>
+      <portlet-mode>VIEW</portlet-mode>
+    </supports>
+    <portlet-info>
+      <title>TestPortlet</title>
+    </portlet-info>
+  </portlet>
+</portlet-app>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/tiles-defs-1.1.xml b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/tiles-defs-1.1.xml
new file mode 100644
index 000000000..71f49fd2a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/tiles-defs-1.1.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 1.1//EN"
+       "http://struts.apache.org/dtds/tiles-config_1_1.dtd">
+
+<!-- Definitions for Tiles documentation   -->
+
+<tiles-definitions>
+
+  <definition name="test.definition.old_format" template="/layout.jsp">
+      <put name="title"  value="This is a definition configured in 1.1 format."/>
+      <put name="header" value="/header.jsp"/>
+      <put name="body"   value="/body.jsp"/>
+  </definition>
+
+</tiles-definitions>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/tiles-defs.xml b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/tiles-defs.xml
new file mode 100644
index 000000000..a7d239d0a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/tiles-defs.xml
@@ -0,0 +1,271 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 2.1//EN"
+       "http://tiles.apache.org/dtds/tiles-config_2_1.dtd">
+
+<!-- Definitions for Tiles documentation   -->
+
+<tiles-definitions>
+
+  <!-- =======================================================  -->
+  <!-- Master definition  									-->
+  <!-- =======================================================  -->
+
+  <!-- Doc index page description  -->
+  <definition name="test.inner.definition" template="/layout.jsp">
+      <put-attribute name="title"  value="This is a configured inner definition."/>
+      <put-attribute name="header" value="/header.jsp"/>
+      <put-attribute name="body"   value="/body.jsp"/>
+  </definition>
+
+  <definition name="test.definition" template="/layout.jsp">
+      <put-attribute name="title"  value="This is the title."/>
+      <put-attribute name="header" value="/header.jsp"/>
+      <put-attribute name="body"   value="/body.jsp"/>
+  </definition>
+
+  <definition name="test.definition.expr" template="/layout.jsp">
+      <put-attribute name="title"  expression="This is the title."/>
+      <put-attribute name="header" value="/header.jsp"/>
+      <put-attribute name="body"   value="/body.jsp"/>
+  </definition>
+
+  <definition name="test.definition.ignore" template="/layout_ignore.jsp">
+      <put-attribute name="title"  value="This is the title."/>
+      <put-attribute name="body"   value="/body.jsp"/>
+  </definition>
+
+  <definition name="test.definition.freemarker" template="/layout.ftl">
+      <put-attribute name="title"  value="This is the title."/>
+      <put-attribute name="header" value="/header.jsp"/>
+      <put-attribute name="body"   value="/body.jsp"/>
+  </definition>
+
+  <definition name="test.definition.flush" template="/layout_flush.jsp">
+      <put-attribute name="title"  value="This is the title."/>
+      <put-attribute name="header" value="/header.jsp"/>
+      <put-attribute name="body"   value="/body.jsp"/>
+  </definition>
+
+  <definition name="test.definition.exception" template="/layout.jsp">
+      <put-attribute name="title"  value="This is the title."/>
+      <put-attribute name="title"  value="This is the title."/>
+      <put-attribute name="header" value="/exception.jsp"/>
+      <put-attribute name="body"   value="/body.jsp"/>
+  </definition>
+
+  <definition name="test.composite.definition" template="/layout.jsp">
+      <put-attribute name="title"  value="This is a configured composite definition."/>
+      <put-attribute name="header" value="/header.jsp"/>
+      <put-attribute name="body"   value="test.inner.definition"/>
+  </definition>
+
+  <definition name="test.putAttributes" template="/putattributeslayout.jsp">
+    <put-attribute name="stringTest" value="This is a string" type="string" />
+    <put-list-attribute name="list">
+      <add-attribute value="valueOne" type="string" />
+      <add-attribute value="valueTwo" type="string" />
+      <add-attribute value="valueThree" type="string" />
+    </put-list-attribute>
+  </definition>
+
+  <definition name="test.putAttributes.inherit" extends="test.putAttributes">
+    <put-list-attribute name="list" inherit="true">
+      <add-attribute value="valueFour" type="string" />
+    </put-list-attribute>
+  </definition>
+
+  <definition name="test.putAttributes.inherit" extends="test.putAttributes">
+    <put-list-attribute name="list" inherit="true">
+      <add-attribute value="valueFour" type="string" />
+    </put-list-attribute>
+  </definition>
+
+  <definition name="test.putAttributes.inherit" extends="test.putAttributes">
+    <put-list-attribute name="list" inherit="true">
+      <add-attribute value="valueFour" type="string" />
+    </put-list-attribute>
+  </definition>
+
+  <definition name="test.putAllAttributes" template="/putallattributeslayout.jsp">
+    <put-attribute name="one" value="There should be three more strings" type="string" />
+    <put-attribute name="two" value="One" type="string" />
+    <put-attribute name="three" value="Two" type="string" />
+    <put-attribute name="four" value="Three" type="string" />
+  </definition>
+
+  <definition name="preparer.definition" template="/layout.jsp">
+      <put-attribute name="title"  value="This is the title."/>
+      <put-attribute name="header" value="/header.jsp"/>
+  </definition>
+
+    <definition name="testdispatchservlet" extends="test.definition"/>
+
+  <definition name="preparer.definition.configured" extends="preparer.definition" preparer="org.apache.tiles.test.preparer.TestViewPreparer" />
+
+  <definition name="test.localized.definition" template="/layout.jsp">
+      <put-attribute name="title" value="Default locale" />
+      <put-attribute name="header" value="/header.jsp" />
+      <put-attribute name="body" value="/defaultlocale.jsp" />
+  </definition>
+
+  <definition name="test.definition.appears" extends="test.definition">
+      <put-attribute name="title"  value="This definition appears."/>
+  </definition>
+
+  <definition name="test.definition.does_not_appear" extends="test.definition">
+      <put-attribute name="title"  value="This definition does
+       not appear."/>
+  </definition>
+
+  <definition name="test.definition.appears.configured"
+    extends="test.definition.appears" role="goodrole" />
+
+  <definition name="test.definition.does_not_appear.configured"
+    extends="test.definition.does_not_appear" role="badrole" />
+
+  <definition name="test.definition.roles" template="/layout.jsp">
+      <put-attribute name="title"  value="This is the title."/>
+      <put-attribute name="header" value="/header.jsp" role="goodrole" />
+      <put-attribute name="body"   value="/body.jsp" role="badrole" />
+  </definition>
+
+  <definition name="test.definition.roles.tags" template="/layout_roles.jsp">
+      <put-attribute name="title"  value="This is the title."/>
+      <put-attribute name="header" value="/header.jsp" />
+      <put-attribute name="body"   value="/body.jsp" />
+  </definition>
+
+  <!-- Tests for cascaded attributes -->
+  <definition name="test.overridden.cascaded.definition" template="/layout.jsp">
+      <put-attribute name="title"  value="This is the title." cascade="true" />
+      <put-attribute name="header" value="/alternate-header.jsp" cascade="true"/>
+      <put-attribute name="body"   value="test.inner.definition"/>
+  </definition>
+
+  <definition name="test.inner.cascadable.definition" template="/layout.jsp">
+      <put-attribute name="body"   value="/body.jsp"/>
+  </definition>
+
+  <definition name="test.cascaded.definition" template="/layout.jsp">
+      <put-attribute name="title"  value="This is the title." cascade="true" />
+      <put-attribute name="header" value="/header.jsp" cascade="true"/>
+      <put-attribute name="body"   value="test.inner.cascadable.definition"/>
+  </definition>
+
+  <definition name="test.cascaded.template.definition" template="/layout.jsp">
+      <put-attribute name="title"  value="This is the title." cascade="true" />
+      <put-attribute name="header" value="/header.jsp" cascade="true"/>
+      <put-attribute name="body"   value="/layout_nobody.jsp"/>
+  </definition>
+
+  <definition name="test.cascaded.list.definition" template="/layout.jsp">
+      <put-attribute name="title"  value="This is the title." cascade="true" />
+      <put-attribute name="header" value="/header.jsp" cascade="true"/>
+      <put-attribute name="body"   value="/putattributeslayout.jsp"/>
+      <put-attribute name="stringTest" value="This is a string" type="string" cascade="true" />
+      <put-list-attribute name="list" cascade="true">
+        <add-attribute value="valueOne" type="string" />
+        <add-attribute value="valueTwo" type="string" />
+        <add-attribute value="valueThree" type="string" />
+      </put-list-attribute>
+  </definition>
+
+  <definition name="test.reversed.definition" template="/layout_alt_title.jsp">
+      <put-attribute name="title"  value="This is the title." type="reversed"/>
+      <put-attribute name="header" value="/header.jsp"/>
+      <put-attribute name="body"   value="/body.jsp"/>
+  </definition>
+
+  <definition name="test.nesting.definitions" template="/layout.jsp">
+      <put-attribute name="title"  value="This is the title."/>
+      <put-attribute name="header" value="/header.jsp"/>
+      <put-attribute name="body">
+          <definition template="/layout.jsp">
+              <put-attribute name="title"  value="This is a nested definition."/>
+              <put-attribute name="header" value="/header.jsp"/>
+              <put-attribute name="body"   value="/body.jsp"/>
+          </definition>
+      </put-attribute>
+  </definition>
+
+  <definition name="test.nesting.list.definitions" template="/layout_list.jsp">
+      <put-attribute name="title"  value="This is the title."/>
+      <put-attribute name="header" value="/header.jsp"/>
+      <put-list-attribute name="list">
+          <add-attribute>
+              <definition template="/layout.jsp">
+                  <put-attribute name="title"  value="This is a nested definition."/>
+                  <put-attribute name="header" value="/header.jsp"/>
+                  <put-attribute name="body"   value="/body.jsp"/>
+              </definition>
+          </add-attribute>
+      </put-list-attribute>
+  </definition>
+
+  <definition name="test.composite.el.definition" templateExpression="${layout}"
+        preparer="org.apache.tiles.test.preparer.RequestSettingViewPreparer">
+      <put-attribute name="title"  value="This is a configured composite definition."/>
+      <put-attribute name="header" value="/header.jsp"/>
+      <put-attribute name="body"   expression="${requestScope.body}"/>
+  </definition>
+
+  <definition name="test.composite.mvel.definition" templateExpression="MVEL:layout"
+        preparer="org.apache.tiles.test.preparer.RequestSettingViewPreparer">
+      <put-attribute name="title"  value="This is a configured composite definition."/>
+      <put-attribute name="header" value="/header.jsp"/>
+      <put-attribute name="body"   expression="MVEL:requestScope.body"/>
+  </definition>
+
+  <definition name="test.composite.ognl.definition" templateExpression="OGNL:layout"
+        preparer="org.apache.tiles.test.preparer.RequestSettingViewPreparer">
+      <put-attribute name="title"  value="This is a configured composite definition."/>
+      <put-attribute name="header" value="/header.jsp"/>
+      <put-attribute name="body"   expression="OGNL:requestScope.body"/>
+  </definition>
+
+  <definition name="test.composite.el.doNotShow.definition" templateExpression="${layout}"
+        preparer="org.apache.tiles.test.preparer.RequestSettingViewPreparer">
+      <put-attribute name="title"  value="This is a configured definition."/>
+      <put-attribute name="header" value="/header.jsp"/>
+      <put-attribute name="body"   expression="${requestScope.doNotShowBody}"/>
+  </definition>
+
+  <definition name="test.definition.attribute.preparer" template="/layout_preparer.jsp">
+      <put-attribute name="title"  value="This is the title."/>
+      <put-attribute name="header" value="/header.jsp"/>
+  </definition>
+
+  <definition name="test.openbody.definition" template="/layout_closebody.jsp">
+      <put-attribute name="title"  value="This is the title."/>
+      <put-attribute name="header" value="/header.jsp"/>
+      <put-attribute name="body"   value="/layout.jsp" />
+  </definition>
+
+  <definition name="test.defaultvalues.definition" template="/layout_default.jsp">
+      <put-attribute name="title"  value="This is the title."/>
+  </definition>
+</tiles-definitions>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/tiles-defs_en_GB.xml b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/tiles-defs_en_GB.xml
new file mode 100644
index 000000000..ccac30ab4
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/tiles-defs_en_GB.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
+       "http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
+
+<!-- Definitions for Tiles documentation   -->
+
+<tiles-definitions>
+  <definition name="test.localized.definition" template="/layout.jsp">
+      <put-attribute name="title" value="British English locale" />
+      <put-attribute name="header" value="/header.jsp" />
+      <put-attribute name="body" value="/defaultlocale.jsp" />
+  </definition>
+
+</tiles-definitions>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/tiles-defs_en_US.xml b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/tiles-defs_en_US.xml
new file mode 100644
index 000000000..8c5090fdf
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/tiles-defs_en_US.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
+       "http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
+
+<!-- Definitions for Tiles documentation   -->
+
+<tiles-definitions>
+  <definition name="test.localized.definition" template="/layout.jsp">
+      <put-attribute name="title" value="American English locale" />
+      <put-attribute name="header" value="/header.jsp" />
+      <put-attribute name="body" value="/defaultlocale.jsp" />
+  </definition>
+
+</tiles-definitions>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/tiles-defs_fr.xml b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/tiles-defs_fr.xml
new file mode 100644
index 000000000..2a4e83d01
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/tiles-defs_fr.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
+       "http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
+
+<!-- Definitions for Tiles documentation   -->
+
+<tiles-definitions>
+  <definition name="test.localized.definition" template="/layout.jsp">
+      <put-attribute name="title" value="French locale" />
+      <put-attribute name="header" value="/header.jsp" />
+      <put-attribute name="body" value="/defaultlocale.jsp" />
+  </definition>
+
+</tiles-definitions>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/tiles-defs_it.xml b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/tiles-defs_it.xml
new file mode 100644
index 000000000..bc8db02b5
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/tiles-defs_it.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
+       "http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
+
+<!-- Definitions for Tiles documentation   -->
+
+<tiles-definitions>
+  <definition name="test.localized.definition" template="/layout.jsp">
+      <put-attribute name="title" value="Italian locale" />
+      <put-attribute name="header" value="/header.jsp" />
+      <put-attribute name="body" value="/defaultlocale.jsp" />
+  </definition>
+
+</tiles-definitions>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/tiles-defs_with_undescore.xml b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/tiles-defs_with_undescore.xml
new file mode 100644
index 000000000..9833af6e6
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/tiles-defs_with_undescore.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
+       "http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
+
+<!-- Definitions for Tiles documentation   -->
+
+<tiles-definitions>
+  <definition name="test.non.localized.definition" template="/layout.jsp">
+      <put-attribute name="title" value="Non localized definition" />
+      <put-attribute name="header" value="/header.jsp" />
+      <put-attribute name="body" value="/body.jsp" />
+  </definition>
+
+</tiles-definitions>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/tools.xml b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/tools.xml
new file mode 100644
index 000000000..3a07bf4f6
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/tools.xml
@@ -0,0 +1,28 @@
+<?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.
+-->
+<tools>
+  <toolbox scope="request">
+    <tool key="exc" class="org.apache.tiles.test.velocity.ExceptionTool"/>
+    <tool class="org.apache.velocity.tools.generic.ContextTool"/>
+  </toolbox>
+  <toolbox scope="application">
+     <tool class="org.apache.velocity.tools.generic.EscapeTool"/>
+   </toolbox>
+</tools>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/velocity.properties b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/velocity.properties
new file mode 100644
index 000000000..805a9e41a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/velocity.properties
@@ -0,0 +1,129 @@
+# 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.
+
+# ----------------------------------------------------------------------------
+# These are the default properties for the
+# Velocity Runtime. These values are used when
+# Runtime.init() is called, and when Runtime.init(properties)
+# fails to find the specificed properties file.
+# ----------------------------------------------------------------------------
+
+
+# ----------------------------------------------------------------------------
+# R U N T I M E  L O G
+# ----------------------------------------------------------------------------
+# Velocity uses the Servlet APIs logging facilites.
+
+# ----------------------------------------------------------------------------
+# This controls if Runtime.error(), info() and warn() messages include the
+# whole stack trace. The last property controls whether invalid references
+# are logged.
+# ----------------------------------------------------------------------------
+
+runtime.log.invalid.reference = true
+
+
+# ----------------------------------------------------------------------------
+# T E M P L A T E  E N C O D I N G
+# ----------------------------------------------------------------------------
+
+input.encoding=ISO-8859-1
+output.encoding=ISO-8859-1
+
+
+# ----------------------------------------------------------------------------
+# F O R E A C H  P R O P E R T I E S
+# ----------------------------------------------------------------------------
+# These properties control how the counter is accessed in the #foreach
+# directive. By default the reference $velocityCount will be available
+# in the body of the #foreach directive. The default starting value
+# for this reference is 1.
+# ----------------------------------------------------------------------------
+
+directive.foreach.counter.name = velocityCount
+directive.foreach.counter.initial.value = 1
+
+
+# ----------------------------------------------------------------------------
+# I N C L U D E  P R O P E R T I E S
+# ----------------------------------------------------------------------------
+# These are the properties that governed the way #include'd content
+# is governed.
+# ----------------------------------------------------------------------------
+
+directive.include.output.errormsg.start = <!-- include error :
+directive.include.output.errormsg.end   =  see error log -->
+
+
+# ----------------------------------------------------------------------------
+# P A R S E  P R O P E R T I E S
+# ----------------------------------------------------------------------------
+
+directive.parse.max.depth = 10
+
+
+# ----------------------------------------------------------------------------
+# VELOCIMACRO PROPERTIES
+# ----------------------------------------------------------------------------
+# global : name of default global library.  It is expected to be in the regular
+# template path.  You may remove it (either the file or this property) if
+# you wish with no harm.
+# ----------------------------------------------------------------------------
+# dev-changes by Marino
+resource.loader=class, webapp, string
+
+class.resource.loader.class=org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader
+
+webapp.resource.loader.cache = true
+webapp.resource.loader.modificationCheckInterval = 5
+velocimacro.library.autoreload = false
+velocimacro.library = /WEB-INF/VM_global_library.vm
+
+velocimacro.permissions.allow.inline = true
+velocimacro.permissions.allow.inline.to.replace.global = false
+velocimacro.permissions.allow.inline.local.scope = false
+
+velocimacro.context.localscope = false
+
+# ----------------------------------------------------------------------------
+# INTERPOLATION
+# ----------------------------------------------------------------------------
+# turn off and on interpolation of references and directives in string
+# literals.  ON by default :)
+# ----------------------------------------------------------------------------
+runtime.interpolate.string.literals = true
+
+
+# ----------------------------------------------------------------------------
+# RESOURCE MANAGEMENT
+# ----------------------------------------------------------------------------
+# Allows alternative ResourceManager and ResourceCache implementations
+# to be plugged in.
+# ----------------------------------------------------------------------------
+resource.manager.class = org.apache.velocity.runtime.resource.ResourceManagerImpl
+resource.manager.cache.class = org.apache.velocity.runtime.resource.ResourceCacheImpl
+
+userdirective=org.apache.tiles.velocity.template.AddAttributeDirective,\
+  org.apache.tiles.velocity.template.AddListAttributeDirective,\
+  org.apache.tiles.velocity.template.DefinitionDirective,\
+  org.apache.tiles.velocity.template.GetAsStringDirective,\
+  org.apache.tiles.velocity.template.ImportAttributeDirective,\
+  org.apache.tiles.velocity.template.InsertAttributeDirective,\
+  org.apache.tiles.velocity.template.InsertDefinitionDirective,\
+  org.apache.tiles.velocity.template.InsertTemplateDirective,\
+  org.apache.tiles.velocity.template.PutAttributeDirective,\
+  org.apache.tiles.velocity.template.PutListAttributeDirective
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/velocity/tiles-defs-1.1.xml b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/velocity/tiles-defs-1.1.xml
new file mode 100644
index 000000000..32b5b3d42
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/velocity/tiles-defs-1.1.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 1.1//EN"
+       "http://struts.apache.org/dtds/tiles-config_1_1.dtd">
+
+<!-- Definitions for Tiles documentation   -->
+
+<tiles-definitions>
+
+  <definition name="velocity.test.definition.old_format" template="/velocity/layout.vm">
+      <put name="title"  value="This is a definition configured in 1.1 format."/>
+      <put name="header" value="/velocity/header.vm"/>
+      <put name="body"   value="/velocity/body.vm"/>
+  </definition>
+
+</tiles-definitions>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/velocity/tiles-defs.xml b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/velocity/tiles-defs.xml
new file mode 100644
index 000000000..c2b974c13
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/velocity/tiles-defs.xml
@@ -0,0 +1,252 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 2.1//EN"
+       "http://tiles.apache.org/dtds/tiles-config_2_1.dtd">
+
+<!-- Definitions for Tiles documentation   -->
+
+<tiles-definitions>
+
+  <!-- =======================================================  -->
+  <!-- Master definition  									-->
+  <!-- =======================================================  -->
+
+  <!-- Doc index page description  -->
+  <definition name="velocity.test.inner.definition" template="/velocity/layout.vm" templateType="velocity">
+      <put-attribute name="title"  value="This is a configured inner definition."/>
+      <put-attribute name="header" value="/velocity/header.vm" type="velocity" />
+      <put-attribute name="body"   value="/velocity/body.vm" type="velocity" />
+  </definition>
+
+  <definition name="velocity.test.definition" template="/velocity/layout.vm" templateType="velocity">
+      <put-attribute name="title"  value="This is the title."/>
+      <put-attribute name="header" value="/velocity/header.vm" type="velocity" />
+      <put-attribute name="body"   value="/velocity/body.vm" type="velocity" />
+  </definition>
+
+  <definition name="velocity.test.definition.ignore" template="/velocity/layout_ignore.vm" templateType="velocity">
+      <put-attribute name="title"  value="This is the title."/>
+      <put-attribute name="body"   value="/velocity/body.vm" type="velocity" />
+  </definition>
+
+  <definition name="velocity.test.definition.velocity" template="/velocity/layout.vm" templateType="velocity">
+      <put-attribute name="title"  value="This is the title."/>
+      <put-attribute name="header" value="/velocity/header.vm" type="velocity" />
+      <put-attribute name="body"   value="/velocity/body.vm" type="velocity" />
+  </definition>
+
+  <definition name="velocity.test.definition.flush" template="/velocity/layout_flush.vm" templateType="velocity">
+      <put-attribute name="title"  value="This is the title."/>
+      <put-attribute name="header" value="/velocity/header.vm" type="velocity" />
+      <put-attribute name="body"   value="/velocity/body.vm" type="velocity" />
+  </definition>
+
+  <definition name="velocity.test.definition.exception" template="/velocity/layout.vm" templateType="velocity">
+      <put-attribute name="title"  value="This is the title."/>
+      <put-attribute name="header" value="/velocity/exception.vm" type="velocity" />
+      <put-attribute name="body"   value="/velocity/body.vm" type="velocity" />
+  </definition>
+
+  <definition name="velocity.test.composite.definition" template="/velocity/layout.vm" templateType="velocity">
+      <put-attribute name="title"  value="This is a configured composite definition."/>
+      <put-attribute name="header" value="/velocity/header.vm" type="velocity" />
+      <put-attribute name="body"   value="test.inner.definition"/>
+  </definition>
+
+  <definition name="velocity.test.putAttributes" template="/velocity/putattributeslayout.vm" templateType="velocity">
+    <put-attribute name="stringTest" value="This is a string" type="string" />
+    <put-list-attribute name="list">
+      <add-attribute value="valueOne" type="string" />
+      <add-attribute value="valueTwo" type="string" />
+      <add-attribute value="valueThree" type="string" />
+    </put-list-attribute>
+  </definition>
+
+  <definition name="velocity.test.putAttributes.inherit" extends="velocity.test.putAttributes">
+    <put-list-attribute name="list" inherit="true">
+      <add-attribute value="valueFour" type="string" />
+    </put-list-attribute>
+  </definition>
+
+  <definition name="velocity.test.putAllAttributes" template="/velocity/putallattributeslayout.vm" templateType="velocity">
+    <put-attribute name="one" value="There should be three more strings" type="string" />
+    <put-attribute name="two" value="One" type="string" />
+    <put-attribute name="three" value="Two" type="string" />
+    <put-attribute name="four" value="Three" type="string" />
+  </definition>
+
+  <definition name="velocity.preparer.definition" template="/velocity/layout.vm" templateType="velocity">
+      <put-attribute name="title"  value="This is the title."/>
+      <put-attribute name="header" value="/velocity/header.vm" type="velocity" />
+  </definition>
+
+    <definition name="velocity.testdispatchservlet" extends="test.definition"/>
+
+  <definition name="velocity.preparer.definition.configured" extends="preparer.definition" preparer="org.apache.tiles.test.preparer.TestViewPreparer" />
+
+  <definition name="velocity.test.localized.definition" template="/velocity/layout.vm" templateType="velocity">
+      <put-attribute name="title" value="Default locale" />
+      <put-attribute name="header" value="/velocity/header.vm" type="velocity" />
+      <put-attribute name="body" value="/velocity/defaultlocale.vm" type="velocity" />
+  </definition>
+
+  <definition name="velocity.test.definition.appears" extends="test.definition">
+      <put-attribute name="title"  value="This definition appears."/>
+  </definition>
+
+  <definition name="velocity.test.definition.does_not_appear" extends="test.definition">
+      <put-attribute name="title"  value="This definition does
+       not appear."/>
+  </definition>
+
+  <definition name="velocity.test.definition.appears.configured"
+    extends="test.definition.appears" role="goodrole" />
+
+  <definition name="velocity.test.definition.does_not_appear.configured"
+    extends="test.definition.does_not_appear" role="badrole" />
+
+  <definition name="velocity.test.definition.roles" template="/velocity/layout.vm" templateType="velocity">
+      <put-attribute name="title"  value="This is the title."/>
+      <put-attribute name="header" value="/velocity/header.vm" role="goodrole" />
+      <put-attribute name="body"   value="/velocity/body.vm" role="badrole" />
+  </definition>
+
+  <definition name="velocity.test.definition.roles.tags" template="/velocity/layout_roles.vm" templateType="velocity">
+      <put-attribute name="title"  value="This is the title."/>
+      <put-attribute name="header" value="/velocity/header.vm" type="velocity" />
+      <put-attribute name="body"   value="/velocity/body.vm" type="velocity" />
+  </definition>
+
+  <!-- Tests for cascaded attributes -->
+  <definition name="velocity.test.overridden.cascaded.definition" template="/velocity/layout.vm" templateType="velocity">
+      <put-attribute name="title"  value="This is the title." cascade="true" />
+      <put-attribute name="header" value="/velocity/alternate-header.vm" cascade="true"/>
+      <put-attribute name="body"   value="test.inner.definition"/>
+  </definition>
+
+  <definition name="velocity.test.inner.cascadable.definition" template="/velocity/layout.vm" templateType="velocity">
+      <put-attribute name="body"   value="/velocity/body.vm" type="velocity" />
+  </definition>
+
+  <definition name="velocity.test.cascaded.definition" template="/velocity/layout.vm" templateType="velocity">
+      <put-attribute name="title"  value="This is the title." cascade="true" />
+      <put-attribute name="header" value="/velocity/header.vm" cascade="true"/>
+      <put-attribute name="body"   value="test.inner.cascadable.definition"/>
+  </definition>
+
+  <definition name="velocity.test.cascaded.template.definition" template="/velocity/layout.vm" templateType="velocity">
+      <put-attribute name="title"  value="This is the title." cascade="true" />
+      <put-attribute name="header" value="/velocity/header.vm" cascade="true"/>
+      <put-attribute name="body"   value="/velocity/layout_nobody.vm" type="velocity" />
+  </definition>
+
+  <definition name="velocity.test.cascaded.list.definition" template="/velocity/layout.vm" templateType="velocity">
+      <put-attribute name="title"  value="This is the title." cascade="true" />
+      <put-attribute name="header" value="/velocity/header.vm" cascade="true"/>
+      <put-attribute name="body"   value="/velocity/putattributeslayout.vm" type="velocity" />
+      <put-attribute name="stringTest" value="This is a string" type="string" cascade="true" />
+      <put-list-attribute name="list" cascade="true">
+        <add-attribute value="valueOne" type="string" />
+        <add-attribute value="valueTwo" type="string" />
+        <add-attribute value="valueThree" type="string" />
+      </put-list-attribute>
+  </definition>
+
+  <definition name="velocity.test.reversed.definition" template="/velocity/layout_alt_title.vm" templateType="velocity">
+      <put-attribute name="title"  value="This is the title." type="reversed"/>
+      <put-attribute name="header" value="/velocity/header.vm" type="velocity" />
+      <put-attribute name="body"   value="/velocity/body.vm" type="velocity" />
+  </definition>
+
+  <definition name="velocity.test.nesting.definitions" template="/velocity/layout.vm" templateType="velocity">
+      <put-attribute name="title"  value="This is the title."/>
+      <put-attribute name="header" value="/velocity/header.vm" type="velocity" />
+      <put-attribute name="body">
+          <definition template="/velocity/layout.vm" templateType="velocity">
+              <put-attribute name="title"  value="This is a nested definition."/>
+              <put-attribute name="header" value="/velocity/header.vm" type="velocity" />
+              <put-attribute name="body"   value="/velocity/body.vm" type="velocity" />
+          </definition>
+      </put-attribute>
+  </definition>
+
+  <definition name="velocity.test.nesting.list.definitions" template="/velocity/layout_list.vm" templateType="velocity">
+      <put-attribute name="title"  value="This is the title."/>
+      <put-attribute name="header" value="/velocity/header.vm" type="velocity" />
+      <put-list-attribute name="list">
+          <add-attribute>
+              <definition template="/velocity/layout.vm" templateType="velocity">
+                  <put-attribute name="title"  value="This is a nested definition."/>
+                  <put-attribute name="header" value="/velocity/header.vm" type="velocity" />
+                  <put-attribute name="body"   value="/velocity/body.vm" type="velocity" />
+              </definition>
+          </add-attribute>
+      </put-list-attribute>
+  </definition>
+
+  <definition name="velocity.test.composite.el.definition" templateExpression="${layout}"
+        preparer="org.apache.tiles.test.preparer.RequestSettingViewPreparer">
+      <put-attribute name="title"  value="This is a configured composite definition."/>
+      <put-attribute name="header" value="/velocity/header.vm" type="velocity" />
+      <put-attribute name="body"   expression="${requestScope.body}"/>
+  </definition>
+
+  <definition name="velocity.test.composite.mvel.definition" templateExpression="MVEL:layout"
+        preparer="org.apache.tiles.test.preparer.RequestSettingViewPreparer">
+      <put-attribute name="title"  value="This is a configured composite definition."/>
+      <put-attribute name="header" value="/velocity/header.vm" type="velocity" />
+      <put-attribute name="body"   expression="MVEL:requestScope.body"/>
+  </definition>
+
+  <definition name="velocity.test.composite.ognl.definition" templateExpression="OGNL:layout"
+        preparer="org.apache.tiles.test.preparer.RequestSettingViewPreparer">
+      <put-attribute name="title"  value="This is a configured composite definition."/>
+      <put-attribute name="header" value="/velocity/header.vm" type="velocity" />
+      <put-attribute name="body"   expression="OGNL:requestScope.body"/>
+  </definition>
+
+  <definition name="velocity.test.composite.el.doNotShow.definition" templateExpression="${layout}"
+        preparer="org.apache.tiles.test.preparer.RequestSettingViewPreparer">
+      <put-attribute name="title"  value="This is a configured definition."/>
+      <put-attribute name="header" value="/velocity/header.vm" type="velocity" />
+      <put-attribute name="body"   expression="${requestScope.doNotShowBody}"/>
+  </definition>
+
+  <definition name="velocity.test.definition.attribute.preparer" template="/velocity/layout_preparer.vm" templateType="velocity">
+      <put-attribute name="title"  value="This is the title."/>
+      <put-attribute name="header" value="/velocity/header.vm" type="velocity" />
+  </definition>
+
+  <definition name="velocity.test.openbody.definition" template="/velocity/layout_closebody.vm" templateType="velocity">
+      <put-attribute name="title"  value="This is the title."/>
+      <put-attribute name="header" value="/velocity/header.vm" type="velocity" />
+      <put-attribute name="body"   value="/velocity/layout.vm" type="velocity" />
+  </definition>
+
+  <definition name="velocity.test.defaultvalues.definition" template="/velocity/layout_default.vm" templateType="velocity">
+      <put-attribute name="title"  value="This is the title."/>
+  </definition>
+</tiles-definitions>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/velocity/tiles-defs_en_GB.xml b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/velocity/tiles-defs_en_GB.xml
new file mode 100644
index 000000000..c27473749
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/velocity/tiles-defs_en_GB.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
+       "http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
+
+<!-- Definitions for Tiles documentation   -->
+
+<tiles-definitions>
+  <definition name="velocity.test.localized.definition" template="/velocity/layout.vm">
+      <put-attribute name="title" value="British English locale" />
+      <put-attribute name="header" value="/velocity/header.vm" />
+      <put-attribute name="body" value="/velocity/defaultlocale.vm" />
+  </definition>
+
+</tiles-definitions>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/velocity/tiles-defs_en_US.xml b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/velocity/tiles-defs_en_US.xml
new file mode 100644
index 000000000..b43699f31
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/velocity/tiles-defs_en_US.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
+       "http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
+
+<!-- Definitions for Tiles documentation   -->
+
+<tiles-definitions>
+  <definition name="velocity.test.localized.definition" template="/velocity/layout.vm">
+      <put-attribute name="title" value="American English locale" />
+      <put-attribute name="header" value="/velocity/header.vm" />
+      <put-attribute name="body" value="/velocity/defaultlocale.vm" />
+  </definition>
+
+</tiles-definitions>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/velocity/tiles-defs_fr.xml b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/velocity/tiles-defs_fr.xml
new file mode 100644
index 000000000..5a64c7643
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/velocity/tiles-defs_fr.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
+       "http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
+
+<!-- Definitions for Tiles documentation   -->
+
+<tiles-definitions>
+  <definition name="velocity.test.localized.definition" template="/velocity/layout.vm">
+      <put-attribute name="title" value="French locale" />
+      <put-attribute name="header" value="/velocity/header.vm" />
+      <put-attribute name="body" value="/velocity/defaultlocale.vm" />
+  </definition>
+
+</tiles-definitions>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/velocity/tiles-defs_it.xml b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/velocity/tiles-defs_it.xml
new file mode 100644
index 000000000..0280c3330
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/velocity/tiles-defs_it.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
+       "http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
+
+<!-- Definitions for Tiles documentation   -->
+
+<tiles-definitions>
+  <definition name="velocity.test.localized.definition" template="/velocity/layout.vm">
+      <put-attribute name="title" value="Italian locale" />
+      <put-attribute name="header" value="/velocity/header.vm" />
+      <put-attribute name="body" value="/velocity/defaultlocale.vm" />
+  </definition>
+
+</tiles-definitions>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/velocity/tiles-defs_with_undescore.xml b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/velocity/tiles-defs_with_undescore.xml
new file mode 100644
index 000000000..7717cb281
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/velocity/tiles-defs_with_undescore.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+ <!DOCTYPE tiles-definitions PUBLIC
+       "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
+       "http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
+
+<!-- Definitions for Tiles documentation   -->
+
+<tiles-definitions>
+  <definition name="velocity.test.non.localized.definition" template="/velocity/layout.vm">
+      <put-attribute name="title" value="Non localized definition" />
+      <put-attribute name="header" value="/velocity/header.vm" />
+      <put-attribute name="body" value="/velocity/body.vm" />
+  </definition>
+
+</tiles-definitions>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/web.xml b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 000000000..efb53c1c1
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,240 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+
+<web-app xmlns="http://java.sun.com/xml/ns/javaee"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+         version="2.5">
+
+    <display-name>Tiles Test Application</display-name>
+    <distributable/>
+
+    <listener>
+      <listener-class>org.apache.tiles.test.init.InitContextListener</listener-class>
+    </listener>
+    <listener>
+      <listener-class>org.apache.tiles.extras.module.ModularTilesListener</listener-class>
+    </listener>
+    <filter>
+        <filter-name>Tiles Decoration Filter</filter-name>
+        <filter-class>org.apache.tiles.web.util.TilesDecorationFilter</filter-class>
+        <init-param>
+            <param-name>definition</param-name>
+            <param-value>test.definition</param-value>
+        </init-param>
+        <init-param>
+            <param-name>attribute-name</param-name>
+            <param-value>body</param-value>
+        </init-param>
+    </filter>
+
+    <filter>
+        <filter-name>Security Wrapping Filter</filter-name>
+        <filter-class>org.apache.tiles.test.filter.SecurityWrappingFilter</filter-class>
+    </filter>
+
+    <filter-mapping>
+        <filter-name>Tiles Decoration Filter</filter-name>
+        <url-pattern>/testdecorationfilter.jsp</url-pattern>
+        <dispatcher>REQUEST</dispatcher>
+    </filter-mapping>
+
+    <filter-mapping>
+        <filter-name>Tiles Decoration Filter</filter-name>
+        <url-pattern>/freemarker/testdecorationfilter.ftl</url-pattern>
+        <dispatcher>REQUEST</dispatcher>
+    </filter-mapping>
+
+    <filter-mapping>
+        <filter-name>Tiles Decoration Filter</filter-name>
+        <url-pattern>/velocity/testdecorationfilter.vm</url-pattern>
+        <dispatcher>REQUEST</dispatcher>
+    </filter-mapping>
+
+    <filter-mapping>
+        <filter-name>Security Wrapping Filter</filter-name>
+        <url-pattern>/*</url-pattern>
+        <dispatcher>REQUEST</dispatcher>
+    </filter-mapping>
+
+    <!-- Standard Action Servlet Configuration -->
+    <servlet>
+        <servlet-name>freemarker</servlet-name>
+        <servlet-class>org.apache.tiles.request.freemarker.servlet.SharedVariableLoaderFreemarkerServlet</servlet-class>
+
+        <!-- FreemarkerServlet settings: -->
+        <init-param>
+            <param-name>TemplatePath</param-name>
+            <param-value>/</param-value>
+        </init-param>
+        <init-param>
+            <param-name>NoCache</param-name>
+            <param-value>true</param-value>
+        </init-param>
+        <init-param>
+            <param-name>ContentType</param-name>
+            <param-value>text/html</param-value>
+        </init-param>
+
+        <!-- FreeMarker settings: -->
+        <init-param>
+            <param-name>template_update_delay</param-name>
+            <param-value>0</param-value> <!-- 0 is for development only! Use higher value otherwise. -->
+        </init-param>
+        <init-param>
+            <param-name>default_encoding</param-name>
+            <param-value>ISO-8859-1</param-value>
+        </init-param>
+        <init-param>
+            <param-name>number_format</param-name>
+            <param-value>0.##########</param-value>
+        </init-param>
+        <init-param>
+            <param-name>org.apache.tiles.request.freemarker.CUSTOM_SHARED_VARIABLE_FACTORIES</param-name>
+            <param-value>tiles,org.apache.tiles.freemarker.TilesSharedVariableFactory</param-value>
+        </init-param>
+
+        <load-on-startup>5</load-on-startup>
+    </servlet>
+
+    <servlet>
+      <servlet-name>velocity</servlet-name>
+      <servlet-class>org.apache.velocity.tools.view.VelocityViewServlet</servlet-class>
+
+      <!--
+        Unless you plan to put your tools.xml and velocity.properties under
+        different folders or give them different names, then these two
+        init-params are unnecessary. The VelocityViewServlet will
+        automatically look for these files in the following locations.
+      -->
+      <init-param>
+        <param-name>org.apache.velocity.toolbox</param-name>
+        <param-value>/WEB-INF/tools.xml</param-value>
+      </init-param>
+
+      <init-param>
+        <param-name>org.apache.velocity.properties</param-name>
+        <param-value>/WEB-INF/velocity.properties</param-value>
+      </init-param>
+    </servlet>
+
+
+    <servlet>
+        <servlet-name>Tiles Dispatch Servlet</servlet-name>
+        <servlet-class>org.apache.tiles.web.util.TilesDispatchServlet</servlet-class>
+    </servlet>
+
+    <!-- Standard Action Servlet Configuration -->
+    <servlet>
+        <servlet-name>layoutServlet</servlet-name>
+        <servlet-class>org.apache.tiles.test.servlet.IncludingServlet</servlet-class>
+        <init-param>
+            <param-name>include</param-name>
+            <param-value>/layout.jsp</param-value>
+        </init-param>
+        <init-param>
+            <param-name>errorInclude</param-name>
+            <param-value>/errorInclude.jsp</param-value>
+        </init-param>
+    </servlet>
+    <servlet>
+        <servlet-name>selectLocaleServlet</servlet-name>
+        <servlet-class>org.apache.tiles.test.servlet.SelectLocaleServlet</servlet-class>
+        <init-param>
+            <param-name>org.apache.tiles.test.servlet.ServletConfig.DEFINITION_NAME</param-name>
+            <param-value>test.localized.definition</param-value>
+        </init-param>
+    </servlet>
+    <servlet>
+        <servlet-name>selectLocaleServletDb</servlet-name>
+        <servlet-class>org.apache.tiles.test.servlet.SelectLocaleServlet</servlet-class>
+        <init-param>
+            <param-name>org.apache.tiles.test.servlet.ServletConfig.DEFINITION_NAME</param-name>
+            <param-value>test.localized.definition</param-value>
+        </init-param>
+        <init-param>
+            <param-name>org.apache.tiles.test.servlet.ServletConfig.CONTAINER_KEY</param-name>
+            <param-value>db</param-value>
+        </init-param>
+    </servlet>
+    <servlet>
+        <servlet-name>selectLocaleServletFreemarker</servlet-name>
+        <servlet-class>org.apache.tiles.test.servlet.SelectLocaleServlet</servlet-class>
+        <init-param>
+            <param-name>org.apache.tiles.test.servlet.ServletConfig.DEFINITION_NAME</param-name>
+            <param-value>freemarker.test.localized.definition</param-value>
+        </init-param>
+    </servlet>
+    <servlet>
+        <servlet-name>selectLocaleServletVelocity</servlet-name>
+        <servlet-class>org.apache.tiles.test.servlet.SelectLocaleServlet</servlet-class>
+        <init-param>
+            <param-name>org.apache.tiles.test.servlet.ServletConfig.DEFINITION_NAME</param-name>
+            <param-value>velocity.test.localized.definition</param-value>
+        </init-param>
+    </servlet>
+
+    <welcome-file-list>
+        <welcome-file>index.jsp</welcome-file>
+    </welcome-file-list>
+
+    <servlet-mapping>
+        <servlet-name>freemarker</servlet-name>
+        <url-pattern>*.ftl</url-pattern>
+    </servlet-mapping>
+    <servlet-mapping>
+        <servlet-name>layoutServlet</servlet-name>
+        <url-pattern>/servlets/layoutServlet</url-pattern>
+    </servlet-mapping>
+
+    <servlet-mapping>
+        <servlet-name>selectLocaleServlet</servlet-name>
+        <url-pattern>/servlets/selectLocaleServlet</url-pattern>
+    </servlet-mapping>
+
+    <servlet-mapping>
+        <servlet-name>selectLocaleServletDb</servlet-name>
+        <url-pattern>/servlets/selectLocaleServletDb</url-pattern>
+    </servlet-mapping>
+
+    <servlet-mapping>
+        <servlet-name>selectLocaleServletFreemarker</servlet-name>
+        <url-pattern>/freemarker/servlets/selectLocaleServlet</url-pattern>
+    </servlet-mapping>
+
+    <servlet-mapping>
+        <servlet-name>selectLocaleServletVelocity</servlet-name>
+        <url-pattern>/velocity/servlets/selectLocaleServlet</url-pattern>
+    </servlet-mapping>
+
+    <servlet-mapping>
+        <servlet-name>velocity</servlet-name>
+        <url-pattern>*.vm</url-pattern>
+    </servlet-mapping>
+
+    <servlet-mapping>
+        <servlet-name>Tiles Dispatch Servlet</servlet-name>
+        <url-pattern>*.tiles</url-pattern>
+    </servlet-mapping>
+</web-app>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/alternate-header.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/alternate-header.jsp
new file mode 100644
index 000000000..f03f1b7ec
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/alternate-header.jsp
@@ -0,0 +1,26 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<strong>This is the alternate header</strong>
+    
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/body.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/body.jsp
new file mode 100644
index 000000000..a99227c9c
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/body.jsp
@@ -0,0 +1,25 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<div align="center"><b><i>This is a body</i></b></div>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/classpath.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/classpath.jsp
new file mode 100644
index 000000000..01f946313
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/classpath.jsp
@@ -0,0 +1,25 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<div align="center"><b><i>This tile was loaded from the classpath</i></b></div>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/defaultlocale.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/defaultlocale.jsp
new file mode 100644
index 000000000..b74fd94b6
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/defaultlocale.jsp
@@ -0,0 +1,28 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<div align="center"><b><i>
+<div id="defaultLocaleMessage">Your default Locale is <%=request.getLocale().toString() %></div>
+</i></b></div>
+<a href="../selectlocale.jsp">Select another locale</a>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/defaultlocale_db.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/defaultlocale_db.jsp
new file mode 100644
index 000000000..bd1b73c88
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/defaultlocale_db.jsp
@@ -0,0 +1,28 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<div align="center"><b><i>
+<div id="defaultLocaleMessage">Your default Locale is <%=request.getLocale().toString() %></div>
+</i></b></div>
+<a href="../selectlocale_db.jsp">Select another locale</a>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/errorInclude.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/errorInclude.jsp
new file mode 100644
index 000000000..4a2deb3f5
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/errorInclude.jsp
@@ -0,0 +1,25 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+The "force include" attribute has not been set.
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/exception.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/exception.jsp
new file mode 100644
index 000000000..2672be2be
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/exception.jsp
@@ -0,0 +1,26 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<strong>This throws an exception</strong>
+<% throw new Exception("This is a test exception"); %>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/alternate-header.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/alternate-header.ftl
new file mode 100644
index 000000000..abd9e7c9a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/alternate-header.ftl
@@ -0,0 +1,25 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<strong>This is the alternate header</strong>
+    
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/body.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/body.ftl
new file mode 100644
index 000000000..fed2a6a76
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/body.ftl
@@ -0,0 +1,24 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<div align="center"><b><i>This is a body</i></b></div>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/classpath.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/classpath.ftl
new file mode 100644
index 000000000..20f3e88e0
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/classpath.ftl
@@ -0,0 +1,24 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<div align="center"><b><i>This tile was loaded from the classpath</i></b></div>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/defaultlocale.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/defaultlocale.ftl
new file mode 100644
index 000000000..b7f795cf2
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/defaultlocale.ftl
@@ -0,0 +1,27 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<div align="center"><b><i>
+<div id="defaultLocaleMessage">Your default Locale is ${.locale}</div>
+</i></b></div>
+<a href="../selectlocale.ftl">Select another locale</a>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/defaultlocale_db.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/defaultlocale_db.ftl
new file mode 100644
index 000000000..0fd285dd4
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/defaultlocale_db.ftl
@@ -0,0 +1,27 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<div align="center"><b><i>
+<div id="defaultLocaleMessage">Your default Locale is <%=request.getLocale().toString() %></div>
+</i></b></div>
+<a href="../selectlocale_db.ftl">Select another locale</a>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/errorInclude.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/errorInclude.ftl
new file mode 100644
index 000000000..393fc7228
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/errorInclude.ftl
@@ -0,0 +1,24 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+The "force include" attribute has not been set.
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/exception.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/exception.ftl
new file mode 100644
index 000000000..4b8fba903
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/exception.ftl
@@ -0,0 +1,25 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<strong>This throws an exception</strong>
+<#assign testValue=1/0 />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/header.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/header.ftl
new file mode 100644
index 000000000..c17e62dd7
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/header.ftl
@@ -0,0 +1,25 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<strong>This is the header</strong>
+    
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/layout.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/layout.ftl
new file mode 100644
index 000000000..403c96be2
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/layout.ftl
@@ -0,0 +1,34 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<table  border="2"  width="300"  bordercolor="Gray">
+  <tr>
+    <td  bgcolor="Blue"><strong><@tiles.getAsString name="title"/></strong></td>
+  </tr>
+  <tr>
+    <td><@tiles.insertAttribute name="header"/></td>
+  </tr>
+  <tr>
+    <td><@tiles.insertAttribute name="body"/></td>
+  </tr>
+</table>           
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/layoutOne.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/layoutOne.ftl
new file mode 100644
index 000000000..60208d65c
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/layoutOne.ftl
@@ -0,0 +1,37 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<table  border="2"  width="300"  bordercolor="Gray">
+  <tr>
+    <td  bgcolor="yellow">This is layout one.</td>
+  </tr>
+  <tr>
+    <td  bgcolor="Blue"><strong><@tiles.getAsString name="title"/></strong></td>
+  </tr>
+  <tr>
+    <td><@tiles.insertAttribute name="header"/></td>
+  </tr>
+  <tr>
+    <td><@tiles.insertAttribute name="body"/></td>
+  </tr>
+</table>           
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/layoutTwo.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/layoutTwo.ftl
new file mode 100644
index 000000000..1e17428fe
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/layoutTwo.ftl
@@ -0,0 +1,37 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<table  border="2"  width="300"  bordercolor="Gray">
+  <tr>
+    <td  bgcolor="yellow">This is layout two.</td>
+  </tr>
+  <tr>
+    <td  bgcolor="Blue"><strong><@tiles.getAsString name="title"/></strong></td>
+  </tr>
+  <tr>
+    <td><@tiles.insertAttribute name="header"/></td>
+  </tr>
+  <tr>
+    <td><@tiles.insertAttribute name="body"/></td>
+  </tr>
+</table>           
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/layout_alt_title.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/layout_alt_title.ftl
new file mode 100644
index 000000000..4b485de50
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/layout_alt_title.ftl
@@ -0,0 +1,34 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<table  border="2"  width="300"  bordercolor="Gray">
+  <tr>
+    <td  bgcolor="Blue"><strong><@tiles.insertAttribute name="title"/></strong></td>
+  </tr>
+  <tr>
+    <td><@tiles.insertAttribute name="header"/></td>
+  </tr>
+  <tr>
+    <td><@tiles.insertAttribute name="body"/></td>
+  </tr>
+</table>           
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/layout_closebody.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/layout_closebody.ftl
new file mode 100644
index 000000000..71e913309
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/layout_closebody.ftl
@@ -0,0 +1,40 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<table  border="2"  width="300"  bordercolor="Gray">
+  <tr>
+    <td  bgcolor="Blue"><strong><@tiles.getAsString name="title"/></strong></td>
+  </tr>
+  <tr>
+    <td><@tiles.insertAttribute name="header"/></td>
+  </tr>
+  <tr>
+    <td>
+    <@tiles.insertAttribute name="body">
+        <@tiles.putAttribute name="title"  value="This is a customized context" />
+        <@tiles.putAttribute name="header" value="/freemarker/header.ftl" />
+        <@tiles.putAttribute name="body"   value="/freemarker/body.ftl" />
+    </@tiles.insertAttribute>
+    </td>
+  </tr>
+</table>           
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/layout_default.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/layout_default.ftl
new file mode 100644
index 000000000..54b806af3
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/layout_default.ftl
@@ -0,0 +1,34 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<table  border="2"  width="300"  bordercolor="Gray">
+  <tr>
+    <td  bgcolor="Blue"><strong><@tiles.insertAttribute name="title" defaultValue="This is the default title."/></strong></td>
+  </tr>
+  <tr>
+    <td><@tiles.insertAttribute name="header" defaultValue="alternate-header.ftl" defaultValueType="template"/></td>
+  </tr>
+  <tr>
+    <td><@tiles.insertAttribute name="body" defaultValue="This is the default body in the tag."/></td>
+  </tr>
+</table>           
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/layout_flush.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/layout_flush.ftl
new file mode 100644
index 000000000..129b77839
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/layout_flush.ftl
@@ -0,0 +1,34 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<table  border="2"  width="300"  bordercolor="Gray">
+  <tr>
+    <td  bgcolor="Blue"><strong><@tiles.getAsString name="title"/></strong></td>
+  </tr>
+  <tr>
+    <td><@tiles.insertAttribute name="header" flush=true/></td>
+  </tr>
+  <tr>
+    <td><@tiles.insertAttribute name="body" flush=true/></td>
+  </tr>
+</table>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/layout_ignore.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/layout_ignore.ftl
new file mode 100644
index 000000000..e6b39d7e0
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/layout_ignore.ftl
@@ -0,0 +1,34 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<table  border="2"  width="300"  bordercolor="Gray">
+  <tr>
+    <td  bgcolor="Blue"><strong><@tiles.getAsString name="title"/></strong></td>
+  </tr>
+  <tr>
+    <td><@tiles.insertAttribute name="header" ignore=true /></td>
+  </tr>
+  <tr>
+    <td><@tiles.insertAttribute name="body"/></td>
+  </tr>
+</table>           
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/layout_list.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/layout_list.ftl
new file mode 100644
index 000000000..09e434b50
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/layout_list.ftl
@@ -0,0 +1,39 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<table  border="2"  width="300"  bordercolor="Gray">
+  <tr>
+    <td  bgcolor="Blue"><strong><@tiles.getAsString name="title"/></strong></td>
+  </tr>
+  <tr>
+    <td><@tiles.insertAttribute name="header"/></td>
+  </tr>
+  <tr>
+    <td>
+        <@tiles.importAttribute name="list"/>
+        <#list list as attribute>
+            <@tiles.insertAttribute value=attribute />
+        </#list>
+    </td>
+  </tr>
+</table>           
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/layout_nobody.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/layout_nobody.ftl
new file mode 100644
index 000000000..a1e1cc942
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/layout_nobody.ftl
@@ -0,0 +1,31 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<table  border="2"  width="300"  bordercolor="Gray">
+  <tr>
+    <td  bgcolor="Blue"><strong><@tiles.getAsString name="title"/></strong></td>
+  </tr>
+  <tr>
+    <td><@tiles.insertAttribute name="header"/></td>
+  </tr>
+</table>           
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/layout_override.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/layout_override.ftl
new file mode 100644
index 000000000..7f168271a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/layout_override.ftl
@@ -0,0 +1,37 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<table  border="2"  width="300"  bordercolor="Gray">
+  <tr>
+    <td  bgcolor="Green"><strong>This is the overridden template.</strong></td>
+  </tr>
+  <tr>
+    <td  bgcolor="Blue"><strong><@tiles.getAsString name="title"/></strong></td>
+  </tr>
+  <tr>
+    <td><@tiles.insertAttribute name="header"/></td>
+  </tr>
+  <tr>
+    <td><@tiles.insertAttribute name="body"/></td>
+  </tr>
+</table>           
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/layout_preparer.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/layout_preparer.ftl
new file mode 100644
index 000000000..e8c83a32b
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/layout_preparer.ftl
@@ -0,0 +1,35 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<table  border="2"  width="300"  bordercolor="Gray">
+  <tr>
+    <td  bgcolor="Blue"><strong><@tiles.getAsString name="title"/></strong></td>
+  </tr>
+  <tr>
+    <td><@tiles.insertAttribute name="header"/></td>
+  </tr>
+  <tr>
+    <td><@tiles.insertAttribute name="body"
+        preparer="org.apache.tiles.test.preparer.AttributeViewPreparer"/></td>
+  </tr>
+</table>           
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/layout_roles.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/layout_roles.ftl
new file mode 100644
index 000000000..c72e7ba57
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/layout_roles.ftl
@@ -0,0 +1,34 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<table  border="2"  width="300"  bordercolor="Gray">
+  <tr>
+    <td  bgcolor="Blue"><strong><@tiles.getAsString name="title"/></strong></td>
+  </tr>
+  <tr>
+    <td><@tiles.insertAttribute name="header" role="goodrole"/></td>
+  </tr>
+  <tr>
+    <td><@tiles.insertAttribute name="body" role="badrole"/></td>
+  </tr>
+</table>           
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/override.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/override.ftl
new file mode 100644
index 000000000..79640d787
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/override.ftl
@@ -0,0 +1,24 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<div align="center"><b><i>This is an overridden content</i></b></div>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/putallattributeslayout.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/putallattributeslayout.ftl
new file mode 100644
index 000000000..51040a88e
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/putallattributeslayout.ftl
@@ -0,0 +1,31 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.importAttribute/>
+
+${one}
+<ul>
+  <li>${two}</li>
+  <li>${three}</li>
+  <li>${four}</li>
+</ul>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/putattributeslayout.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/putattributeslayout.ftl
new file mode 100644
index 000000000..93f09d00f
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/putattributeslayout.ftl
@@ -0,0 +1,32 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.importAttribute name="stringTest"/>
+<@tiles.importAttribute name="list"/>
+Single attribute "stringTest" value: ${stringTest?html} <br/><br/>
+The attribute "list" contains these values:
+<ul>
+<#list list as item>
+<li><@tiles.insertAttribute value=item /></li>
+</#list>
+</ul>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/selectlocale.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/selectlocale.ftl
new file mode 100644
index 000000000..6b515b810
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/selectlocale.ftl
@@ -0,0 +1,44 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Select your locale</title>
+</head>
+<body>
+<form action="servlets/selectLocaleServlet">
+Select your locale:
+<select name="locale">
+<option selected="selected" value="">Default</option>
+<option value="en_US">American English</option>
+<option value="en_GB">British English</option>
+<option value="fr_FR">French</option>
+<option value="it_IT">Italian</option>
+</select>
+<input type="submit" value="Submit" />
+</form>
+<div id="defaultLocaleMessage">Your default Locale is ${.locale}</div>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testdecorationfilter.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testdecorationfilter.ftl
new file mode 100644
index 000000000..d502e686c
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testdecorationfilter.ftl
@@ -0,0 +1,24 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<i>This Content should be wrapped with the standard layout.</i>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testdef.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testdef.ftl
new file mode 100644
index 000000000..fd4eb0713
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testdef.ftl
@@ -0,0 +1,29 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.definition name="templateDefinition" template="/freemarker/layout.ftl">
+  <@tiles.putAttribute name="title"  value="This is the title." />
+  <@tiles.putAttribute name="header" value="/freemarker/header.ftl" />
+  <@tiles.putAttribute name="body"   value="/freemarker/body.ftl" />
+</@tiles.definition>
+<@tiles.insertDefinition name="templateDefinition" />
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testdef_extend.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testdef_extend.ftl
new file mode 100644
index 000000000..d00921c56
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testdef_extend.ftl
@@ -0,0 +1,30 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.definition name="test.definition.override.one" extends="freemarker.test.definition">
+  <@tiles.putAttribute name="body"   value="/freemarker/override.ftl" />
+</@tiles.definition>
+<@tiles.definition name="test.definition.override.two" extends="test.definition.override.one">
+  <@tiles.putAttribute name="title"   value="This is an overridden title" />
+</@tiles.definition>
+<@tiles.insertDefinition name="test.definition.override.two" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testdef_list_inherit.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testdef_list_inherit.ftl
new file mode 100644
index 000000000..fbb0c9d6b
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testdef_list_inherit.ftl
@@ -0,0 +1,30 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.definition name="templateDefinition" extends="test.putAttributes">
+  <@tiles.putAttribute name="stringTest" value="This is a string" type="string"/>
+  <@tiles.putListAttribute name="list" inherit=true>
+    <@tiles.addAttribute value="valueFour" type="string" />
+  </@tiles.putListAttribute>
+</@tiles.definition>
+<@tiles.insertDefinition name="templateDefinition" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testdef_preparer.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testdef_preparer.ftl
new file mode 100644
index 000000000..07321c0d1
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testdef_preparer.ftl
@@ -0,0 +1,29 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.definition name="templateDefinition" template="/freemarker/layout.ftl" preparer="org.apache.tiles.test.preparer.TestViewPreparer">
+  <@tiles.putAttribute name="title"  value="This is the title." />
+  <@tiles.putAttribute name="header" value="/freemarker/header.ftl" />
+  <@tiles.putAttribute name="body"   value="/freemarker/body.ftl" />
+</@tiles.definition>
+<@tiles.insertDefinition name="templateDefinition" />
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testimportattribute.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testimportattribute.ftl
new file mode 100644
index 000000000..ec93cb824
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testimportattribute.ftl
@@ -0,0 +1,24 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertDefinition name="freemarker.test.putAttributes" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testimportattribute_all.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testimportattribute_all.ftl
new file mode 100644
index 000000000..bfa23ca61
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testimportattribute_all.ftl
@@ -0,0 +1,24 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertDefinition name="freemarker.test.putAllAttributes" />
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testimportattribute_inherit.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testimportattribute_inherit.ftl
new file mode 100644
index 000000000..3b3cf9aa2
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testimportattribute_inherit.ftl
@@ -0,0 +1,24 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertDefinition name="freemarker.test.putAttributes.inherit" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition.ftl
new file mode 100644
index 000000000..95a2ff4c0
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition.ftl
@@ -0,0 +1,24 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertDefinition name="freemarker.test.definition" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_attribute_preparer.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_attribute_preparer.ftl
new file mode 100644
index 000000000..b15569750
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_attribute_preparer.ftl
@@ -0,0 +1,24 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertDefinition name="freemarker.test.definition.attribute.preparer" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_attribute_roles.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_attribute_roles.ftl
new file mode 100644
index 000000000..747239513
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_attribute_roles.ftl
@@ -0,0 +1,24 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertDefinition name="freemarker.test.definition.roles" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_attribute_roles_tags.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_attribute_roles_tags.ftl
new file mode 100644
index 000000000..b845ad6d5
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_attribute_roles_tags.ftl
@@ -0,0 +1,24 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertDefinition name="freemarker.test.definition.roles.tags" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_cascaded.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_cascaded.ftl
new file mode 100644
index 000000000..78f0d919b
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_cascaded.ftl
@@ -0,0 +1,24 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertDefinition name="freemarker.test.cascaded.definition" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_cascaded_list.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_cascaded_list.ftl
new file mode 100644
index 000000000..b9604d88f
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_cascaded_list.ftl
@@ -0,0 +1,24 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertDefinition name="freemarker.test.cascaded.list.definition" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_cascaded_overridden.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_cascaded_overridden.ftl
new file mode 100644
index 000000000..43a921e93
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_cascaded_overridden.ftl
@@ -0,0 +1,24 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertDefinition name="freemarker.test.overridden.cascaded.definition" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_cascaded_template.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_cascaded_template.ftl
new file mode 100644
index 000000000..13af94079
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_cascaded_template.ftl
@@ -0,0 +1,24 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertDefinition name="freemarker.test.cascaded.template.definition" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_classpath.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_classpath.ftl
new file mode 100644
index 000000000..06deeb1e2
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_classpath.ftl
@@ -0,0 +1,24 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertDefinition name="freemarker.classpath.definition" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_composite.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_composite.ftl
new file mode 100644
index 000000000..6b0a36121
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_composite.ftl
@@ -0,0 +1,24 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertDefinition name="freemarker.test.composite.definition" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_composite_tags.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_composite_tags.ftl
new file mode 100644
index 000000000..a560fe39c
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_composite_tags.ftl
@@ -0,0 +1,34 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.definition name="test.inner.definition.tags" template="/freemarker/layout.ftl">
+    <@tiles.putAttribute name="title"  value="This is an inner definition with tags."/>
+    <@tiles.putAttribute name="header" value="/freemarker/header.ftl"/>
+    <@tiles.putAttribute name="body"   value="/freemarker/body.ftl"/>
+</@tiles.definition>
+<@tiles.definition name="test.composite.definition.tags" template="/freemarker/layout.ftl">
+    <@tiles.putAttribute name="title"  value="This is a composite definition with tags."/>
+    <@tiles.putAttribute name="header" value="/freemarker/header.ftl"/>
+    <@tiles.putAttribute name="body"   value="test.inner.definition.tags" type="definition"/>
+</@tiles.definition>
+<@tiles.insertDefinition name="test.composite.definition.tags" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_composite_tags_includes_configured.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_composite_tags_includes_configured.ftl
new file mode 100644
index 000000000..b03555fe8
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_composite_tags_includes_configured.ftl
@@ -0,0 +1,34 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.definition name="test.inner.definition.tags" template="/freemarker/layout.ftl">
+    <@tiles.putAttribute name="title"  value="This is an inner definition with tags."/>
+    <@tiles.putAttribute name="header" value="/freemarker/header.ftl"/>
+    <@tiles.putAttribute name="body"   value="/freemarker/body.ftl"/>
+</@tiles.definition>
+<@tiles.definition name="test.composite.definition.tags" template="/freemarker/layout.ftl">
+    <@tiles.putAttribute name="title"  value="This is a composite definition with tags."/>
+    <@tiles.putAttribute name="header" value="/freemarker/header.ftl"/>
+    <@tiles.putAttribute name="body"   value="test.inner.definition" type="definition"/>
+</@tiles.definition>
+<@tiles.insertDefinition name="test.composite.definition.tags" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_composite_tags_includes_configured_notype.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_composite_tags_includes_configured_notype.ftl
new file mode 100644
index 000000000..b88ac830a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_composite_tags_includes_configured_notype.ftl
@@ -0,0 +1,34 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.definition name="test.inner.definition.tags" template="/freemarker/layout.ftl">
+    <@tiles.putAttribute name="title"  value="This is an inner definition with tags."/>
+    <@tiles.putAttribute name="header" value="/freemarker/header.ftl"/>
+    <@tiles.putAttribute name="body"   value="/freemarker/body.ftl"/>
+</@tiles.definition>
+<@tiles.definition name="test.composite.definition.tags" template="/freemarker/layout.ftl">
+    <@tiles.putAttribute name="title"  value="This is a composite definition with tags."/>
+    <@tiles.putAttribute name="header" value="/freemarker/header.ftl"/>
+    <@tiles.putAttribute name="body"   value="test.inner.definition"/>
+</@tiles.definition>
+<@tiles.insertDefinition name="test.composite.definition.tags" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_composite_tags_notype.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_composite_tags_notype.ftl
new file mode 100644
index 000000000..ad2da7dae
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_composite_tags_notype.ftl
@@ -0,0 +1,34 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.definition name="test.inner.definition.tags" template="/freemarker/layout.ftl">
+    <@tiles.putAttribute name="title"  value="This is an inner definition with tags."/>
+    <@tiles.putAttribute name="header" value="/freemarker/header.ftl"/>
+    <@tiles.putAttribute name="body"   value="/freemarker/body.ftl"/>
+</@tiles.definition>
+<@tiles.definition name="test.composite.definition.tags" template="/freemarker/layout.ftl">
+    <@tiles.putAttribute name="title"  value="This is a composite definition with tags."/>
+    <@tiles.putAttribute name="header" value="/freemarker/header.ftl"/>
+    <@tiles.putAttribute name="body"   value="test.inner.definition.tags"/>
+</@tiles.definition>
+<@tiles.insertDefinition name="test.composite.definition.tags" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_db.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_db.ftl
new file mode 100644
index 000000000..3ad4015cb
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_db.ftl
@@ -0,0 +1,25 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.setCurrentContainer containerKey="db"/>
+<@tiles.insertDefinition name="test.definition" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_defaultvalues.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_defaultvalues.ftl
new file mode 100644
index 000000000..b8a4672a1
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_defaultvalues.ftl
@@ -0,0 +1,24 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertDefinition name="freemarker.test.defaultvalues.definition" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_el.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_el.ftl
new file mode 100644
index 000000000..2763ce6d3
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_el.ftl
@@ -0,0 +1,24 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertDefinition name="freemarker.test.composite.el.definition" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_el_singleeval.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_el_singleeval.ftl
new file mode 100644
index 000000000..a5c7d6a7d
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_el_singleeval.ftl
@@ -0,0 +1,24 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertDefinition name="freemarker.test.composite.el.doNotShow.definition" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_exception.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_exception.ftl
new file mode 100644
index 000000000..9b4cfe9bd
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_exception.ftl
@@ -0,0 +1,24 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertDefinition name="freemarker.test.definition.exception" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_extended_db.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_extended_db.ftl
new file mode 100644
index 000000000..c56461446
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_extended_db.ftl
@@ -0,0 +1,25 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.setCurrentContainer containerKey="db"/>
+<@tiles.insertDefinition name="test.definition.extended" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_flush.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_flush.ftl
new file mode 100644
index 000000000..59268b3fe
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_flush.ftl
@@ -0,0 +1,24 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertDefinition name="freemarker.test.definition.flush" flush=true/>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_freemarker.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_freemarker.ftl
new file mode 100644
index 000000000..d7c2d859e
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_freemarker.ftl
@@ -0,0 +1,24 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertDefinition name="freemarker.test.definition.freemarker" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_ignore.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_ignore.ftl
new file mode 100644
index 000000000..071c88ac9
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_ignore.ftl
@@ -0,0 +1,24 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertDefinition name="freemarker.test.definition.ignore" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_inline.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_inline.ftl
new file mode 100644
index 000000000..b4f0e72f8
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_inline.ftl
@@ -0,0 +1,28 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertDefinition name="freemarker.test.definition">
+  <@tiles.putAttribute name="body">
+  <div align="center"><b><i>This is an inline content</i></b></div>
+  </@tiles.putAttribute>
+</@tiles.insertDefinition>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_mvel.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_mvel.ftl
new file mode 100644
index 000000000..2620e79cd
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_mvel.ftl
@@ -0,0 +1,24 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertDefinition name="freemarker.test.composite.mvel.definition" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_ognl.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_ognl.ftl
new file mode 100644
index 000000000..cac46e3b7
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_ognl.ftl
@@ -0,0 +1,24 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertDefinition name="freemarker.test.composite.ognl.definition" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_old.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_old.ftl
new file mode 100644
index 000000000..bbe599ecd
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_old.ftl
@@ -0,0 +1,24 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertDefinition name="freemarker.test.definition.old_format" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_openbody.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_openbody.ftl
new file mode 100644
index 000000000..1b9b8dc3d
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_openbody.ftl
@@ -0,0 +1,24 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertDefinition name="freemarker.test.openbody.definition" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_override.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_override.ftl
new file mode 100644
index 000000000..08b8f0524
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_override.ftl
@@ -0,0 +1,26 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertDefinition name="freemarker.test.definition">
+  <@tiles.putAttribute name="body"   value="/freemarker/override.ftl" />
+</@tiles.insertDefinition>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_override_and_not.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_override_and_not.ftl
new file mode 100644
index 000000000..14fa71b33
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_override_and_not.ftl
@@ -0,0 +1,30 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+Overridden content:<br/>
+<@tiles.insertDefinition name="freemarker.test.definition">
+  <@tiles.putAttribute name="body"   value="/freemarker/override.ftl" />
+</@tiles.insertDefinition>
+<br/>
+Not overridden content:<br/>
+<@tiles.insertDefinition name="freemarker.test.definition" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_override_template.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_override_template.ftl
new file mode 100644
index 000000000..c4dddd8f3
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_override_template.ftl
@@ -0,0 +1,24 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertDefinition name="freemarker.test.definition" template="/freemarker/layout_override.ftl" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_preparer.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_preparer.ftl
new file mode 100644
index 000000000..1958fb716
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_preparer.ftl
@@ -0,0 +1,24 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertDefinition name="freemarker.preparer.definition" preparer="org.apache.tiles.test.preparer.TestViewPreparer" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_preparer_configured.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_preparer_configured.ftl
new file mode 100644
index 000000000..afe676641
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_preparer_configured.ftl
@@ -0,0 +1,24 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertDefinition name="freemarker.preparer.definition.configured"/>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_regexp.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_regexp.ftl
new file mode 100644
index 000000000..622a0df2a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_regexp.ftl
@@ -0,0 +1,26 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.setCurrentContainer containerKey="alternate" />
+<@tiles.insertDefinition name="freemarker.test.regexp.definitionOne.messageHello" />
+<@tiles.insertDefinition name="freemarker.test.regexp.definitionTwo.messageBye" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_reversed.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_reversed.ftl
new file mode 100644
index 000000000..7f3cd5408
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_reversed.ftl
@@ -0,0 +1,24 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertDefinition name="freemarker.test.reversed.definition" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_role.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_role.ftl
new file mode 100644
index 000000000..530a4cc83
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_role.ftl
@@ -0,0 +1,25 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertDefinition name="freemarker.test.definition.appears.configured" />
+<@tiles.insertDefinition name="freemarker.test.definition.does_not_appear.configured" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_role_tag.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_role_tag.ftl
new file mode 100644
index 000000000..9f2feeeeb
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_role_tag.ftl
@@ -0,0 +1,25 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertDefinition name="freemarker.test.definition.appears" role="goodrole" />
+<@tiles.insertDefinition name="freemarker.test.definition.does_not_appear" role="badrole" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_wildcard.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_wildcard.ftl
new file mode 100644
index 000000000..4ab8a5c34
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertdefinition_wildcard.ftl
@@ -0,0 +1,26 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.setCurrentContainer containerKey="alternate" />
+<@tiles.insertDefinition name="freemarker.test.definitionOne.messageHello" />
+<@tiles.insertDefinition name="freemarker.test.definitionTwo.messageBye" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertnesteddefinition.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertnesteddefinition.ftl
new file mode 100644
index 000000000..60d68397e
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertnesteddefinition.ftl
@@ -0,0 +1,24 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertDefinition name="freemarker.test.nesting.definitions" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertnesteddefinition_tags.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertnesteddefinition_tags.ftl
new file mode 100644
index 000000000..59b1e13ca
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertnesteddefinition_tags.ftl
@@ -0,0 +1,35 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.definition name="test.nesting.definitions.tags" template="/freemarker/layout.ftl">
+    <@tiles.putAttribute name="title"  value="This is the title."/>
+    <@tiles.putAttribute name="header" value="/freemarker/header.ftl"/>
+    <@tiles.putAttribute name="body">
+        <@tiles.definition template="/freemarker/layout.ftl">
+            <@tiles.putAttribute name="title"  value="This is a nested definition."/>
+            <@tiles.putAttribute name="header" value="/freemarker/header.ftl"/>
+            <@tiles.putAttribute name="body"   value="/freemarker/body.ftl"/>
+        </@tiles.definition>
+    </@tiles.putAttribute>
+</@tiles.definition>
+<@tiles.insertDefinition name="test.nesting.definitions.tags" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertnestedlistdefinition.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertnestedlistdefinition.ftl
new file mode 100644
index 000000000..0e80379a9
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertnestedlistdefinition.ftl
@@ -0,0 +1,24 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertDefinition name="freemarker.test.nesting.list.definitions" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertnestedlistdefinition_tags.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertnestedlistdefinition_tags.ftl
new file mode 100644
index 000000000..aa47d12f5
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testinsertnestedlistdefinition_tags.ftl
@@ -0,0 +1,37 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.definition name="test.nesting.definitions.tags" template="/freemarker/layout_list.ftl">
+    <@tiles.putAttribute name="title"  value="This is the title."/>
+    <@tiles.putAttribute name="header" value="/freemarker/header.ftl"/>
+    <@tiles.putListAttribute name="list">
+        <@tiles.addAttribute>
+	        <@tiles.definition template="/freemarker/layout.ftl">
+	            <@tiles.putAttribute name="title"  value="This is a nested definition."/>
+	            <@tiles.putAttribute name="header" value="/freemarker/header.ftl"/>
+	            <@tiles.putAttribute name="body"   value="/freemarker/body.ftl"/>
+	        </@tiles.definition>
+        </@tiles.addAttribute>
+    </@tiles.putListAttribute>
+</@tiles.definition>
+<@tiles.insertDefinition name="test.nesting.definitions.tags" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testput.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testput.ftl
new file mode 100644
index 000000000..5219ca80d
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testput.ftl
@@ -0,0 +1,28 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertTemplate template="/freemarker/layout.ftl">
+  <@tiles.putAttribute name="title"  value="This is the title." />
+  <@tiles.putAttribute name="header" value="/freemarker/header.ftl" />
+  <@tiles.putAttribute name="body"   value="/freemarker/body.ftl" />
+</@tiles.insertTemplate>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testput_cascaded.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testput_cascaded.ftl
new file mode 100644
index 000000000..0d97ee63d
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testput_cascaded.ftl
@@ -0,0 +1,28 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertTemplate template="/freemarker/layout.ftl">
+  <@tiles.putAttribute name="title"  value="This is the title." cascade=true />
+  <@tiles.putAttribute name="header" value="/freemarker/header.ftl" cascade=true />
+  <@tiles.putAttribute name="body"   value="test.inner.cascadable.definition" />
+</@tiles.insertTemplate>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testput_cascaded_overridden.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testput_cascaded_overridden.ftl
new file mode 100644
index 000000000..172d3928c
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testput_cascaded_overridden.ftl
@@ -0,0 +1,28 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertTemplate template="/freemarker/layout.ftl">
+  <@tiles.putAttribute name="title"  value="This is the title." cascade=true />
+  <@tiles.putAttribute name="header" value="/freemarker/alternate-header.ftl" cascade=true />
+  <@tiles.putAttribute name="body"   value="test.inner.definition" />
+</@tiles.insertTemplate>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testput_cascaded_template.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testput_cascaded_template.ftl
new file mode 100644
index 000000000..464933303
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testput_cascaded_template.ftl
@@ -0,0 +1,28 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertTemplate template="/freemarker/layout.ftl">
+  <@tiles.putAttribute name="title"  value="This is the title." cascade=true />
+  <@tiles.putAttribute name="header" value="/freemarker/header.ftl" cascade=true />
+  <@tiles.putAttribute name="body"   value="/freemarker/layout_nobody.ftl" />
+</@tiles.insertTemplate>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testput_el.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testput_el.ftl
new file mode 100644
index 000000000..c8b7bb042
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testput_el.ftl
@@ -0,0 +1,30 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<#assign bodyContent="Body Content defined by and el" />
+
+<@tiles.insertTemplate template="/freemarker/layout.ftl">
+  <@tiles.putAttribute name="title"  value="This is the title." />
+  <@tiles.putAttribute name="header" value="/freemarker/header.ftl" />
+  <@tiles.putAttribute name="body"   value=bodyContent />
+</@tiles.insertTemplate>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testput_el_singleeval.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testput_el_singleeval.ftl
new file mode 100644
index 000000000..9992db3d4
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testput_el_singleeval.ftl
@@ -0,0 +1,31 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<#assign doNotShowBody="$" + "{" + "requestScope.doNotShow}" />
+<#assign doNotShow="DO NOT SHOW!!!" />
+
+<@tiles.insertTemplate template="/freemarker/layout.ftl">
+  <@tiles.putAttribute name="title"  value="This is the title." />
+  <@tiles.putAttribute name="header" value="/freemarker/header.ftl" />
+  <@tiles.putAttribute name="body"   value=doNotShowBody />
+</@tiles.insertTemplate>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testput_flush.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testput_flush.ftl
new file mode 100644
index 000000000..180156c8b
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testput_flush.ftl
@@ -0,0 +1,28 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertTemplate template="/freemarker/layout.ftl" flush=true>
+  <@tiles.putAttribute name="title"  value="This is the title." />
+  <@tiles.putAttribute name="header" value="/freemarker/header.ftl" />
+  <@tiles.putAttribute name="body"   value="/freemarker/body.ftl" />
+</@tiles.insertTemplate>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testput_reversed.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testput_reversed.ftl
new file mode 100644
index 000000000..c2c6f36d7
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testput_reversed.ftl
@@ -0,0 +1,28 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertTemplate template="/freemarker/layout_alt_title.ftl">
+  <@tiles.putAttribute name="title"  value="This is the title." type="reversed" />
+  <@tiles.putAttribute name="header" value="/freemarker/header.ftl" />
+  <@tiles.putAttribute name="body"   value="/freemarker/body.ftl" />
+</@tiles.insertTemplate>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testput_servlet.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testput_servlet.ftl
new file mode 100644
index 000000000..2bb373d94
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testput_servlet.ftl
@@ -0,0 +1,28 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertTemplate template="/servlets/layoutServlet">
+  <@tiles.putAttribute name="title"  value="This is the title." />
+  <@tiles.putAttribute name="header" value="/freemarker/header.ftl" />
+  <@tiles.putAttribute name="body"   value="/freemarker/body.ftl" />
+</@tiles.insertTemplate>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testputlist.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testputlist.ftl
new file mode 100644
index 000000000..737bcc8c8
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testputlist.ftl
@@ -0,0 +1,31 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertTemplate template="/freemarker/putattributeslayout.ftl">
+  <@tiles.putAttribute name="stringTest" value="This is a string" type="string" />
+  <@tiles.putListAttribute name="list">
+    <@tiles.addAttribute value="valueOne" type="string" />
+    <@tiles.addAttribute value="valueTwo" type="string" />
+    <@tiles.addAttribute value="valueThree" type="string" />
+  </@tiles.putListAttribute>
+</@tiles.insertTemplate>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testputlist_cascaded.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testputlist_cascaded.ftl
new file mode 100644
index 000000000..8bf974f77
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testputlist_cascaded.ftl
@@ -0,0 +1,34 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertTemplate template="/freemarker/layout.ftl">
+  <@tiles.putAttribute name="title"  value="This is the title." />
+  <@tiles.putAttribute name="header" value="/freemarker/header.ftl" />
+  <@tiles.putAttribute name="body"   value="/freemarker/putattributeslayout.ftl" />
+  <@tiles.putAttribute name="stringTest" value="This is a string" type="string" cascade=true />
+  <@tiles.putListAttribute name="list" cascade=true>
+    <@tiles.addAttribute value="valueOne" type="string" />
+    <@tiles.addAttribute value="valueTwo" type="string" />
+    <@tiles.addAttribute value="valueThree" type="string" />
+  </@tiles.putListAttribute>
+</@tiles.insertTemplate>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testputlist_inherit.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testputlist_inherit.ftl
new file mode 100644
index 000000000..fec8e78f6
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testputlist_inherit.ftl
@@ -0,0 +1,28 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertDefinition name="freemarker.test.putAttributes">
+  <@tiles.putListAttribute name="list" inherit=true>
+    <@tiles.addAttribute value="valueFour" type="string" />
+  </@tiles.putListAttribute>
+</@tiles.insertDefinition>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testsetcurrentcontainer.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testsetcurrentcontainer.ftl
new file mode 100644
index 000000000..eb00701a5
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testsetcurrentcontainer.ftl
@@ -0,0 +1,27 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.setCurrentContainer containerKey="alternate" />
+<@tiles.insertDefinition name="freemarker.test.definition" />
+<@tiles.setCurrentContainer />
+<@tiles.insertDefinition name="freemarker.test.definition" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testunderscores_nolocale.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testunderscores_nolocale.ftl
new file mode 100644
index 000000000..b5f55d174
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/freemarker/testunderscores_nolocale.ftl
@@ -0,0 +1,24 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<@tiles.insertDefinition name="freemarker.test.non.localized.definition" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/header.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/header.jsp
new file mode 100644
index 000000000..78dd41457
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/header.jsp
@@ -0,0 +1,26 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<strong>This is the header</strong>
+    
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/index.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/index.jsp
new file mode 100644
index 000000000..f2e99a3bd
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/index.jsp
@@ -0,0 +1,311 @@
+<%@ page session="false" %>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<html>
+<head>
+    <title>Tiles 2 Test Application</title>
+</head>
+
+<body>
+    <h1>Tiles 2 Test Application</h1>
+
+    <h1>JSP-based tests</h1>
+
+    <h2>Features in Tiles 2.0.x</h2>
+
+    <h3>Standard Render/Attribute Tests</h3>
+    <a href="testinsertdefinition.jsp">Test Insert Configured Definition</a><br/>
+    <a href="testinsertdefinitionexpr.jsp">Test Insert Configured Definition With Expression</a><br/>
+    <a href="testinsertdefinition_ignore.jsp">Test Insert Configured Definition with Ignore</a><br/>
+    <a href="testinsertdefinition_flush.jsp">Test Insert Configured Definition with Flush</a><br/>
+    <a href="testinsertdefinition_preparer.jsp">Test Insert Configured Definition with Preparer</a><br/>
+    <a href="testinsertdefinition_preparer_configured.jsp">Test Insert Configured Definition with Preparer configured in the definition itself</a><br/>
+    <a href="testinsertdefinition_classpath.jsp">Test Insert Configured Classpath Definition</a><br/>
+    <a href="testinsertdefinition_override.jsp">Test Insert Configured Definition with an overridden content</a><br/>
+    <a href="testinsertdefinition_override_and_not.jsp">Test Insert Configured Definition with an overridden content and one with original content</a><br/>
+    <a href="testinsertdefinition_inline.jsp">Test Insert Configured Definition with an inline content</a><br/>
+    <a href="testinsertdefinition_composite.jsp">Test Insert Configured Definition that contains another definition inside</a><br/>
+    <a href="testinsertdefinition_exception.jsp">Test Insert Configured Definition with an exception in an attribute page</a><br/>
+    <a href="testinsertdefinition_freemarker.jsp">Test Insert Configured Definition with FreeMarker</a><br/>
+    <a href="testinsertdefinition_openbody.jsp">Test Insert Configured Definition with Open Body</a><br/>
+    <a href="testput.jsp">Test Put Tag</a><br/>
+    <a href="testput_flush.jsp">Test Put Tag with Flush</a><br/>
+    <a href="testput_el.jsp">Test Put Tag using EL</a><br/>
+    <a href="testput_servlet.jsp">Test Put Tag using a servlet mapping as a template</a><br/>
+    <a href="testputlist.jsp">Test Put List Tag</a><br/>
+    <a href="testimportattribute.jsp">Test importAttribute Tag</a><br/>
+    <a href="testimportattribute_all.jsp">Test importAttribute Tag with no name</a><br/>
+    <a href="testdecorationfilter.jsp">Test Tiles Definition Filter</a><br/>
+    <a href="testdispatchservlet.tiles">Test Tiles Dispatch Servlet</a><br/>
+    <a href="selectlocale.jsp">Test Localization</a><br/>
+
+    <h3>Mutable Container Tests</h3>
+    <a href="testdef.jsp">Test Definition Tag</a><br/>
+    <a href="testdef_extend.jsp">Test Definition Tag extending configured and custom definitions</a><br/>
+    <a href="testdef_preparer.jsp">Test Definition Tag with Preparer</a><br/>
+    <a href="testinsertdefinition_composite_tags_includes_configured.jsp">Test Insert Definition that contains another definition inside (configured via tiles-defs.xml) using JSP tags</a><br/>
+    <a href="testinsertdefinition_composite_tags.jsp">Test Insert Definition that contains another definition inside using JSP tags</a><br/>
+    <a href="testinsertdefinition_composite_tags_includes_configured_notype.jsp">Test Insert Definition that contains another definition inside (configured via tiles-defs.xml) using JSP tags without types</a><br/>
+    <a href="testinsertdefinition_composite_tags_notype.jsp">Test Insert Definition that contains another definition inside using JSP tags without types</a><br/></body>
+
+    <h3>Roles Verification tests</h3>
+    <a href="testinsertdefinition_role.jsp">Test Insert Configured Definition with Specified Role</a><br/>
+    <a href="testinsertdefinition_role_tag.jsp">Test Insert Configured Definition with Specified Role in Tag</a><br/>
+    <a href="testinsertdefinition_attribute_roles.jsp">Test Insert Configured Definition with Attribute that have Roles</a><br/>
+    <a href="testinsertdefinition_attribute_roles_tags.jsp">Test Insert Configured Definition with Attribute that have Roles in Tags</a><br/>
+
+    <h2>Features in Tiles 2.1.x</h2>
+
+    <h3>Standard Render/Attribute Tests</h3>
+    <a href="testinsertdefinition_override_template.jsp">Test Insert Configured Definition with an overridden template</a><br/>
+    <a href="testinsertdefinition_old.jsp">Test Insert Configured Definition in Old Format</a><br/>
+    <a href="testinsertdefinition_cascaded.jsp">Test Insert Configured Cascaded Definition</a><br/>
+    <a href="testinsertdefinition_cascaded_overridden.jsp">Test Insert Configured Cascaded Definition with Override</a><br/>
+    <a href="testinsertdefinition_cascaded_template.jsp">Test Insert Configured Cascaded Definition with Template</a><br/>
+    <a href="testinsertdefinition_cascaded_list.jsp">Test Insert Configured Cascaded Definition with List</a><br/>
+    <a href="testinsertdefinition_reversed.jsp">Test Insert Configured Definition with Reversed Attribute</a><br/>
+    <a href="testinsertdefinition_attribute_preparer.jsp">Test Insert Configured Definition with Attribute Preparer</a><br/>
+    <a href="testinsertnesteddefinition.jsp">Test Insert Nested Definition</a><br/>
+    <a href="testinsertnesteddefinition_tags.jsp">Test Insert Nested Definition only using JSP tags</a><br/>
+    <a href="testinsertnestedlistdefinition.jsp">Test Insert Nested List Definition</a><br/>
+    <a href="testinsertnestedlistdefinition_tags.jsp">Test Insert Nested List Definition only using JSP tags</a><br/>
+    <a href="testinsertdefinition_el.jsp">Test Insert Configured Definition with EL</a><br/>
+    <a href="testinsertdefinition_el_singleeval.jsp">Test Insert Configured Definition with EL to test Single Evaluation</a><br/>
+    <a href="testinsertdefinition_wildcard.jsp">Test Insert Configured Definition with Wildcards</a><br/>
+    <a href="testinsertdefinition_defaultvalues.jsp">Test Insert Configured Definition with Default Values</a><br/>
+    <a href="testput_cascaded.jsp">Test Put Tag with Cascaded Attributes</a><br/>
+    <a href="testput_cascaded_overridden.jsp">Test Put Tag with Overridden Cascaded Attributes</a><br/>
+    <a href="testput_cascaded_template.jsp">Test Put Tag with Cascaded Attributes and Template</a><br/>
+    <a href="testput_el_singleeval.jsp">Test Put Tag using EL to test Single Evaluation</a><br/>
+    <a href="testput_reversed.jsp">Test Put Tag with Reversed Attribute</a><br/>
+    <a href="testputlist_cascaded.jsp">Test Put List Cascaded Tag</a><br/>
+    <a href="testputlist_inherit.jsp">Test Put List Tag with Inherit</a><br/>
+    <a href="testimportattribute_inherit.jsp">Test importAttribute Tag with List Inherit</a><br/>
+    <a href="testsetcurrentcontainer.jsp">Test setCurrentContainer Tag</a><br/>
+
+    <h3>Mutable Container Tests</h3>
+    <a href="testdef_list_inherit.jsp">Test Definition Tag with a List Inherit</a><br/>
+
+    <h3>Database Verification tests</h3>
+    <a href="testinsertdefinition_db.jsp">Test Insert Configured Definition from DB</a><br/>
+    <a href="testinsertdefinition_extended_db.jsp">Test Insert Extended Configured Definition from DB</a><br/>
+    <a href="selectlocale_db.jsp">Test Localization from DB</a><br/>
+
+    <h2>Features in Tiles 2.2.x</h2>
+
+    <h3>Standard Render/Attribute Tests</h3>
+    <a href="testinsertdefinition_mvel.jsp">Test Insert Configured Definition with MVEL</a><br/>
+    <a href="testinsertdefinition_ognl.jsp">Test Insert Configured Definition with OGNL</a><br/>
+    <a href="testinsertdefinition_regexp.jsp">Test Insert Configured Definition with Regular Expression</a><br/>
+
+    <h2>Features in Tiles 3.0.x</h2>
+
+    <h3>TILES-571</h3>
+    <a href="testunderscores_nolocale.jsp">Test underscores without localization</a>
+
+	<h1>FreeMarker-based tests</h1>
+
+    <h2>Features in Tiles 2.0.x</h2>
+
+    <h3>Standard Render/Attribute Tests</h3>
+    <a href="freemarker/testinsertdefinition.ftl">FreeMarker: Test Insert Configured Definition</a><br/>
+    <a href="freemarker/testinsertdefinition_ignore.ftl">FreeMarker: Test Insert Configured Definition with Ignore</a><br/>
+    <a href="freemarker/testinsertdefinition_flush.ftl">FreeMarker: Test Insert Configured Definition with Flush</a><br/>
+    <a href="freemarker/testinsertdefinition_preparer.ftl">FreeMarker: Test Insert Configured Definition with Preparer</a><br/>
+    <a href="freemarker/testinsertdefinition_preparer_configured.ftl">FreeMarker: Test Insert Configured Definition with Preparer configured in the definition itself</a><br/>
+    <a href="freemarker/testinsertdefinition_classpath.ftl">FreeMarker: Test Insert Configured Classpath Definition</a><br/>
+    <a href="freemarker/testinsertdefinition_override.ftl">FreeMarker: Test Insert Configured Definition with an overridden content</a><br/>
+    <a href="freemarker/testinsertdefinition_override_and_not.ftl">FreeMarker: Test Insert Configured Definition with an overridden content and one with original content</a><br/>
+    <a href="freemarker/testinsertdefinition_inline.ftl">FreeMarker: Test Insert Configured Definition with an inline content</a><br/>
+    <a href="freemarker/testinsertdefinition_composite.ftl">FreeMarker: Test Insert Configured Definition that contains another definition inside</a><br/>
+    <a href="freemarker/testinsertdefinition_exception.ftl">FreeMarker: Test Insert Configured Definition with an exception in an attribute page</a><br/>
+    <a href="freemarker/testinsertdefinition_openbody.ftl">FreeMarker: Test Insert Configured Definition with Open Body</a><br/>
+    <a href="freemarker/testput.ftl">FreeMarker: Test Put Tag</a><br/>
+    <a href="freemarker/testput_flush.ftl">FreeMarker: Test Put Tag with Flush</a><br/>
+    <a href="freemarker/testput_el.ftl">FreeMarker: Test Put Tag using EL</a><br/>
+    <a href="freemarker/testput_servlet.ftl">FreeMarker: Test Put Tag using a servlet mapping as a template</a><br/>
+    <a href="freemarker/testputlist.ftl">FreeMarker: Test Put List Tag</a><br/>
+    <a href="freemarker/testimportattribute.ftl">FreeMarker: Test importAttribute Tag</a><br/>
+    <a href="freemarker/testimportattribute_all.ftl">FreeMarker: Test importAttribute Tag with no name</a><br/>
+    <a href="freemarker/testdecorationfilter.ftl">FreeMarker: Test Tiles Definition Filter</a><br/>
+    <a href="freemarker.testdispatchservlet.tiles">FreeMarker: Test Tiles Dispatch Servlet</a><br/>
+    <a href="freemarker/selectlocale.ftl">FreeMarker: Test Localization</a><br/>
+
+    <h3>Mutable Container Tests</h3>
+    <a href="freemarker/testdef.ftl">FreeMarker: Test Definition Tag</a><br/>
+    <a href="freemarker/testdef_extend.ftl">FreeMarker: Test Definition Tag extending configured and custom definitions</a><br/>
+    <a href="freemarker/testdef_preparer.ftl">FreeMarker: Test Definition Tag with Preparer</a><br/>
+    <a href="freemarker/testinsertdefinition_composite_tags_includes_configured.ftl">FreeMarker: Test Insert Definition that contains another definition inside (configured via tiles-defs.xml) using JSP tags</a><br/>
+    <a href="freemarker/testinsertdefinition_composite_tags.ftl">FreeMarker: Test Insert Definition that contains another definition inside using JSP tags</a><br/>
+    <a href="freemarker/testinsertdefinition_composite_tags_includes_configured_notype.ftl">FreeMarker: Test Insert Definition that contains another definition inside (configured via tiles-defs.xml) using JSP tags without types</a><br/>
+    <a href="freemarker/testinsertdefinition_composite_tags_notype.ftl">FreeMarker: Test Insert Definition that contains another definition inside using JSP tags without types</a><br/>
+
+    <h3>Roles Verification tests</h3>
+    <a href="freemarker/testinsertdefinition_role.ftl">FreeMarker: Test Insert Configured Definition with Specified Role</a><br/>
+    <a href="freemarker/testinsertdefinition_role_tag.ftl">FreeMarker: Test Insert Configured Definition with Specified Role in Tag</a><br/>
+    <a href="freemarker/testinsertdefinition_attribute_roles.ftl">FreeMarker: Test Insert Configured Definition with Attribute that have Roles</a><br/>
+    <a href="freemarker/testinsertdefinition_attribute_roles_tags.ftl">FreeMarker: Test Insert Configured Definition with Attribute that have Roles in Tags</a><br/>
+
+    <h2>Features in Tiles 2.1.x</h2>
+
+    <h3>Standard Render/Attribute Tests</h3>
+    <a href="freemarker/testinsertdefinition_override_template.ftl">FreeMarker: Test Insert Configured Definition with an overridden template</a><br/>
+    <a href="freemarker/testinsertdefinition_old.ftl">FreeMarker: Test Insert Configured Definition in Old Format</a><br/>
+    <a href="freemarker/testinsertdefinition_cascaded.ftl">FreeMarker: Test Insert Configured Cascaded Definition</a><br/>
+    <a href="freemarker/testinsertdefinition_cascaded_overridden.ftl">FreeMarker: Test Insert Configured Cascaded Definition with Override</a><br/>
+    <a href="freemarker/testinsertdefinition_cascaded_template.ftl">FreeMarker: Test Insert Configured Cascaded Definition with Template</a><br/>
+    <a href="freemarker/testinsertdefinition_cascaded_list.ftl">FreeMarker: Test Insert Configured Cascaded Definition with List</a><br/>
+    <a href="freemarker/testinsertdefinition_reversed.ftl">FreeMarker: Test Insert Configured Definition with Reversed Attribute</a><br/>
+    <a href="freemarker/testinsertdefinition_attribute_preparer.ftl">FreeMarker: Test Insert Configured Definition with Attribute Preparer</a><br/>
+    <a href="freemarker/testinsertnesteddefinition.ftl">FreeMarker: Test Insert Nested Definition</a><br/>
+    <a href="freemarker/testinsertnesteddefinition_tags.ftl">FreeMarker: Test Insert Nested Definition only using JSP tags</a><br/>
+    <a href="freemarker/testinsertnestedlistdefinition.ftl">FreeMarker: Test Insert Nested List Definition</a><br/>
+    <a href="freemarker/testinsertnestedlistdefinition_tags.ftl">FreeMarker: Test Insert Nested List Definition only using JSP tags</a><br/>
+    <a href="freemarker/testinsertdefinition_el.ftl">FreeMarker: Test Insert Configured Definition with EL</a><br/>
+    <a href="freemarker/testinsertdefinition_el_singleeval.ftl">FreeMarker: Test Insert Configured Definition with EL to test Single Evaluation</a><br/>
+    <a href="freemarker/testinsertdefinition_wildcard.ftl">FreeMarker: Test Insert Configured Definition with Wildcards</a><br/>
+    <a href="freemarker/testinsertdefinition_defaultvalues.ftl">FreeMarker: Test Insert Configured Definition with Default Values</a><br/>
+    <a href="freemarker/testput_cascaded.ftl">FreeMarker: Test Put Tag with Cascaded Attributes</a><br/>
+    <a href="freemarker/testput_cascaded_overridden.ftl">FreeMarker: Test Put Tag with Overridden Cascaded Attributes</a><br/>
+    <a href="freemarker/testput_cascaded_template.ftl">FreeMarker: Test Put Tag with Cascaded Attributes and Template</a><br/>
+    <a href="freemarker/testput_el_singleeval.ftl">FreeMarker: Test Put Tag using EL to test Single Evaluation</a><br/>
+    <a href="freemarker/testput_reversed.ftl">FreeMarker: Test Put Tag with Reversed Attribute</a><br/>
+    <a href="freemarker/testputlist_cascaded.ftl">FreeMarker: Test Put List Cascaded Tag</a><br/>
+    <a href="freemarker/testputlist_inherit.ftl">FreeMarker: Test Put List Tag with Inherit</a><br/>
+    <a href="freemarker/testimportattribute_inherit.ftl">FreeMarker: Test importAttribute Tag with List Inherit</a><br/>
+    <a href="freemarker/testsetcurrentcontainer.ftl">FreeMarker: Test setCurrentContainer Tag</a><br/>
+
+    <h3>Mutable Container Tests</h3>
+    <a href="freemarker/testdef_list_inherit.ftl">FreeMarker: Test Definition Tag with a List Inherit</a><br/>
+
+    <h3>Database Verification tests</h3>
+    <a href="freemarker/testinsertdefinition_db.ftl">FreeMarker: Test Insert Configured Definition from DB</a><br/>
+    <a href="freemarker/testinsertdefinition_extended_db.ftl">FreeMarker: Test Insert Extended Configured Definition from DB</a><br/>
+
+    <h2>Features in Tiles 2.2.x</h2>
+
+    <h3>Standard Render/Attribute Tests</h3>
+    <a href="freemarker/testinsertdefinition_mvel.ftl">FreeMarker: Test Insert Configured Definition with MVEL</a><br/>
+    <a href="freemarker/testinsertdefinition_ognl.ftl">FreeMarker: Test Insert Configured Definition with OGNL</a><br/>
+    <a href="freemarker/testinsertdefinition_regexp.ftl">FreeMarker: Test Insert Configured Definition with Regular Expression</a><br/>
+    <a href="org/apache/tiles/test/alt/freemarker/testinsertdefinition_alt.ftl">FreeMarker: Test Insert Configured Definition in Module</a><br/>
+
+    <h2>Features in Tiles 3.0.x</h2>
+
+    <h3>TILES-571</h3>
+    <a href="freemarker/testunderscores_nolocale.ftl">FreeMarker: Test underscores without localization</a>
+
+    <h1>Velocity-based tests</h1>
+
+    <h2>Features in Tiles 2.0.x</h2>
+
+    <h3>Standard Render/Attribute Tests</h3>
+    <a href="velocity/testinsertdefinition.vm">Velocity: Test Insert Configured Definition</a><br/>
+    <a href="velocity/testinsertdefinition_ignore.vm">Velocity: Test Insert Configured Definition with Ignore</a><br/>
+    <a href="velocity/testinsertdefinition_flush.vm">Velocity: Test Insert Configured Definition with Flush</a><br/>
+    <a href="velocity/testinsertdefinition_preparer.vm">Velocity: Test Insert Configured Definition with Preparer</a><br/>
+    <a href="velocity/testinsertdefinition_preparer_configured.vm">Velocity: Test Insert Configured Definition with Preparer configured in the definition itself</a><br/>
+    <a href="velocity/testinsertdefinition_classpath.vm">Velocity: Test Insert Configured Classpath Definition</a><br/>
+    <a href="velocity/testinsertdefinition_override.vm">Velocity: Test Insert Configured Definition with an overridden content</a><br/>
+    <a href="velocity/testinsertdefinition_override_and_not.vm">Velocity: Test Insert Configured Definition with an overridden content and one with original content</a><br/>
+    <a href="velocity/testinsertdefinition_inline.vm">Velocity: Test Insert Configured Definition with an inline content</a><br/>
+    <a href="velocity/testinsertdefinition_composite.vm">Velocity: Test Insert Configured Definition that contains another definition inside</a><br/>
+    <a href="velocity/testinsertdefinition_exception.vm">Velocity: Test Insert Configured Definition with an exception in an attribute page</a><br/>
+    <a href="velocity/testinsertdefinition_openbody.vm">Velocity: Test Insert Configured Definition with Open Body</a><br/>
+    <a href="velocity/testput.vm">Velocity: Test Put Tag</a><br/>
+    <a href="velocity/testput_flush.vm">Velocity: Test Put Tag with Flush</a><br/>
+    <a href="velocity/testput_el.vm">Velocity: Test Put Tag using EL</a><br/>
+    <a href="velocity/testput_servlet.vm">Velocity: Test Put Tag using a servlet mapping as a template</a><br/>
+    <a href="velocity/testputlist.vm">Velocity: Test Put List Tag</a><br/>
+    <a href="velocity/testimportattribute.vm">Velocity: Test importAttribute Tag</a><br/>
+    <a href="velocity/testimportattribute_all.vm">Velocity: Test importAttribute Tag with no name</a><br/>
+    <a href="velocity/testdecorationfilter.vm">Velocity: Test Tiles Definition Filter</a><br/>
+    <a href="velocity.testdispatchservlet.tiles">Velocity: Test Tiles Dispatch Servlet</a><br/>
+    <a href="velocity/selectlocale.vm">Velocity: Test Localization</a><br/>
+
+    <h3>Mutable Container Tests</h3>
+    <a href="velocity/testdef.vm">Velocity: Test Definition Tag</a><br/>
+    <a href="velocity/testdef_extend.vm">Velocity: Test Definition Tag extending configured and custom definitions</a><br/>
+    <a href="velocity/testdef_preparer.vm">Velocity: Test Definition Tag with Preparer</a><br/>
+    <a href="velocity/testinsertdefinition_composite_tags_includes_configured.vm">Velocity: Test Insert Definition that contains another definition inside (configured via tiles-defs.xml) using JSP tags</a><br/>
+    <a href="velocity/testinsertdefinition_composite_tags.vm">Velocity: Test Insert Definition that contains another definition inside using JSP tags</a><br/>
+    <a href="velocity/testinsertdefinition_composite_tags_includes_configured_notype.vm">Velocity: Test Insert Definition that contains another definition inside (configured via tiles-defs.xml) using JSP tags without types</a><br/>
+    <a href="velocity/testinsertdefinition_composite_tags_notype.vm">Velocity: Test Insert Definition that contains another definition inside using JSP tags without types</a><br/>
+
+    <h3>Roles Verification tests</h3>
+    <a href="velocity/testinsertdefinition_role.vm">Velocity: Test Insert Configured Definition with Specified Role</a><br/>
+    <a href="velocity/testinsertdefinition_role_tag.vm">Velocity: Test Insert Configured Definition with Specified Role in Tag</a><br/>
+    <a href="velocity/testinsertdefinition_attribute_roles.vm">Velocity: Test Insert Configured Definition with Attribute that have Roles</a><br/>
+    <a href="velocity/testinsertdefinition_attribute_roles_tags.vm">Velocity: Test Insert Configured Definition with Attribute that have Roles in Tags</a><br/>
+
+    <h2>Features in Tiles 2.1.x</h2>
+
+    <h3>Standard Render/Attribute Tests</h3>
+    <a href="velocity/testinsertdefinition_override_template.vm">Velocity: Test Insert Configured Definition with an overridden template</a><br/>
+    <a href="velocity/testinsertdefinition_old.vm">Velocity: Test Insert Configured Definition in Old Format</a><br/>
+    <a href="velocity/testinsertdefinition_cascaded.vm">Velocity: Test Insert Configured Cascaded Definition</a><br/>
+    <a href="velocity/testinsertdefinition_cascaded_overridden.vm">Velocity: Test Insert Configured Cascaded Definition with Override</a><br/>
+    <a href="velocity/testinsertdefinition_cascaded_template.vm">Velocity: Test Insert Configured Cascaded Definition with Template</a><br/>
+    <a href="velocity/testinsertdefinition_cascaded_list.vm">Velocity: Test Insert Configured Cascaded Definition with List</a><br/>
+    <a href="velocity/testinsertdefinition_reversed.vm">Velocity: Test Insert Configured Definition with Reversed Attribute</a><br/>
+    <a href="velocity/testinsertdefinition_attribute_preparer.vm">Velocity: Test Insert Configured Definition with Attribute Preparer</a><br/>
+    <a href="velocity/testinsertnesteddefinition.vm">Velocity: Test Insert Nested Definition</a><br/>
+    <a href="velocity/testinsertnesteddefinition_tags.vm">Velocity: Test Insert Nested Definition only using JSP tags</a><br/>
+    <a href="velocity/testinsertnestedlistdefinition.vm">Velocity: Test Insert Nested List Definition</a><br/>
+    <a href="velocity/testinsertnestedlistdefinition_tags.vm">Velocity: Test Insert Nested List Definition only using JSP tags</a><br/>
+    <a href="velocity/testinsertdefinition_el.vm">Velocity: Test Insert Configured Definition with EL</a><br/>
+    <a href="velocity/testinsertdefinition_el_singleeval.vm">Velocity: Test Insert Configured Definition with EL to test Single Evaluation</a><br/>
+    <a href="velocity/testinsertdefinition_wildcard.vm">Velocity: Test Insert Configured Definition with Wildcards</a><br/>
+    <a href="velocity/testinsertdefinition_defaultvalues.vm">Velocity: Test Insert Configured Definition with Default Values</a><br/>
+    <a href="velocity/testput_cascaded.vm">Velocity: Test Put Tag with Cascaded Attributes</a><br/>
+    <a href="velocity/testput_cascaded_overridden.vm">Velocity: Test Put Tag with Overridden Cascaded Attributes</a><br/>
+    <a href="velocity/testput_cascaded_template.vm">Velocity: Test Put Tag with Cascaded Attributes and Template</a><br/>
+    <a href="velocity/testput_el_singleeval.vm">Velocity: Test Put Tag using EL to test Single Evaluation</a><br/>
+    <a href="velocity/testput_reversed.vm">Velocity: Test Put Tag with Reversed Attribute</a><br/>
+    <a href="velocity/testputlist_cascaded.vm">Velocity: Test Put List Cascaded Tag</a><br/>
+    <a href="velocity/testputlist_inherit.vm">Velocity: Test Put List Tag with Inherit</a><br/>
+    <a href="velocity/testimportattribute_inherit.vm">Velocity: Test importAttribute Tag with List Inherit</a><br/>
+    <a href="velocity/testsetcurrentcontainer.vm">Velocity: Test setCurrentContainer Tag</a><br/>
+
+    <h3>Mutable Container Tests</h3>
+    <a href="velocity/testdef_list_inherit.vm">Velocity: Test Definition Tag with a List Inherit</a><br/>
+
+    <h3>Database Verification tests</h3>
+    <a href="velocity/testinsertdefinition_db.vm">Velocity: Test Insert Configured Definition from DB</a><br/>
+    <a href="velocity/testinsertdefinition_extended_db.vm">Velocity: Test Insert Extended Configured Definition from DB</a><br/>
+
+    <h2>Features in Tiles 2.2.x</h2>
+
+    <h3>Standard Render/Attribute Tests</h3>
+    <a href="velocity/testinsertdefinition_mvel.vm">Velocity: Test Insert Configured Definition with MVEL</a><br/>
+    <a href="velocity/testinsertdefinition_ognl.vm">Velocity: Test Insert Configured Definition with OGNL</a><br/>
+    <a href="velocity/testinsertdefinition_regexp.vm">Velocity: Test Insert Configured Definition with Regular Expression</a><br/>
+    <a href="org/apache/tiles/test/alt/velocity/testinsertdefinition_alt.vm">Velocity: Test Insert Configured Definition in Module</a><br/>
+
+    <h2>Features in Tiles 3.0.x</h2>
+
+    <h3>TILES-571</h3>
+    <a href="velocity/testunderscores_nolocale.vm">Velocity: Test underscores without localization</a>
+
+</html>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layout.ftl b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layout.ftl
new file mode 100644
index 000000000..c7ba7d114
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layout.ftl
@@ -0,0 +1,37 @@
+<#--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<table  border="2"  width="300"  bordercolor="Gray">
+  <tr>
+    <td  bgcolor="Blue"><strong><@tiles.getAsString name="title"/></strong></td>
+  </tr>
+  <tr>
+    <td><@tiles.insertAttribute name="header"/></td>
+  </tr>
+  <tr>
+    <td><@tiles.insertAttribute name="body"/></td>
+  </tr>
+  <tr>
+    <td>This layout is made in FreeMarker.</td>
+  </tr>
+</table>           
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layout.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layout.jsp
new file mode 100644
index 000000000..23d3cc0b2
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layout.jsp
@@ -0,0 +1,37 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<table  border="2"  width="300"  bordercolor="Gray">
+  <tr>
+    <td  bgcolor="Blue"><strong><tiles:getAsString name="title"/></strong></td>
+  </tr>
+  <tr>
+    <td><tiles:insertAttribute name="header"/></td>
+  </tr>
+  <tr>
+    <td><tiles:insertAttribute name="body"/></td>
+  </tr>
+</table>           
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layoutOne.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layoutOne.jsp
new file mode 100644
index 000000000..05545b5ea
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layoutOne.jsp
@@ -0,0 +1,40 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<table  border="2"  width="300"  bordercolor="Gray">
+  <tr>
+    <td  bgcolor="yellow">This is layout one.</td>
+  </tr>
+  <tr>
+    <td  bgcolor="Blue"><strong><tiles:getAsString name="title"/></strong></td>
+  </tr>
+  <tr>
+    <td><tiles:insertAttribute name="header"/></td>
+  </tr>
+  <tr>
+    <td><tiles:insertAttribute name="body"/></td>
+  </tr>
+</table>           
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layoutTwo.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layoutTwo.jsp
new file mode 100644
index 000000000..4d5cd25a2
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layoutTwo.jsp
@@ -0,0 +1,40 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<table  border="2"  width="300"  bordercolor="Gray">
+  <tr>
+    <td  bgcolor="yellow">This is layout two.</td>
+  </tr>
+  <tr>
+    <td  bgcolor="Blue"><strong><tiles:getAsString name="title"/></strong></td>
+  </tr>
+  <tr>
+    <td><tiles:insertAttribute name="header"/></td>
+  </tr>
+  <tr>
+    <td><tiles:insertAttribute name="body"/></td>
+  </tr>
+</table>           
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layout_alt_title.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layout_alt_title.jsp
new file mode 100644
index 000000000..e84ed4fac
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layout_alt_title.jsp
@@ -0,0 +1,37 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<table  border="2"  width="300"  bordercolor="Gray">
+  <tr>
+    <td  bgcolor="Blue"><strong><tiles:insertAttribute name="title"/></strong></td>
+  </tr>
+  <tr>
+    <td><tiles:insertAttribute name="header"/></td>
+  </tr>
+  <tr>
+    <td><tiles:insertAttribute name="body"/></td>
+  </tr>
+</table>           
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layout_closebody.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layout_closebody.jsp
new file mode 100644
index 000000000..1b4f6fbfb
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layout_closebody.jsp
@@ -0,0 +1,43 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<table  border="2"  width="300"  bordercolor="Gray">
+  <tr>
+    <td  bgcolor="Blue"><strong><tiles:getAsString name="title"/></strong></td>
+  </tr>
+  <tr>
+    <td><tiles:insertAttribute name="header"/></td>
+  </tr>
+  <tr>
+    <td>
+    <tiles:insertAttribute name="body">
+        <tiles:putAttribute name="title"  value="This is a customized context" />
+        <tiles:putAttribute name="header" value="/header.jsp" />
+        <tiles:putAttribute name="body"   value="/body.jsp" />
+    </tiles:insertAttribute>
+    </td>
+  </tr>
+</table>           
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layout_default.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layout_default.jsp
new file mode 100644
index 000000000..4c6ccbed2
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layout_default.jsp
@@ -0,0 +1,37 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<table  border="2"  width="300"  bordercolor="Gray">
+  <tr>
+    <td  bgcolor="Blue"><strong><tiles:insertAttribute name="title" defaultValue="This is the default title."/></strong></td>
+  </tr>
+  <tr>
+    <td><tiles:insertAttribute name="header" defaultValue="alternate-header.jsp" defaultValueType="template"/></td>
+  </tr>
+  <tr>
+    <td><tiles:insertAttribute name="body" defaultValue="This is the default body in the tag."/></td>
+  </tr>
+</table>           
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layout_expr.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layout_expr.jsp
new file mode 100644
index 000000000..23d3cc0b2
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layout_expr.jsp
@@ -0,0 +1,37 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<table  border="2"  width="300"  bordercolor="Gray">
+  <tr>
+    <td  bgcolor="Blue"><strong><tiles:getAsString name="title"/></strong></td>
+  </tr>
+  <tr>
+    <td><tiles:insertAttribute name="header"/></td>
+  </tr>
+  <tr>
+    <td><tiles:insertAttribute name="body"/></td>
+  </tr>
+</table>           
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layout_flush.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layout_flush.jsp
new file mode 100644
index 000000000..fd3fbd5c4
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layout_flush.jsp
@@ -0,0 +1,37 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<table  border="2"  width="300"  bordercolor="Gray">
+  <tr>
+    <td  bgcolor="Blue"><strong><tiles:getAsString name="title"/></strong></td>
+  </tr>
+  <tr>
+    <td><tiles:insertAttribute name="header" flush="true"/></td>
+  </tr>
+  <tr>
+    <td><tiles:insertAttribute name="body" flush="true"/></td>
+  </tr>
+</table>           
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layout_ignore.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layout_ignore.jsp
new file mode 100644
index 000000000..8dc32bc9e
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layout_ignore.jsp
@@ -0,0 +1,37 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<table  border="2"  width="300"  bordercolor="Gray">
+  <tr>
+    <td  bgcolor="Blue"><strong><tiles:getAsString name="title"/></strong></td>
+  </tr>
+  <tr>
+    <td><tiles:insertAttribute name="header" ignore="true"/></td>
+  </tr>
+  <tr>
+    <td><tiles:insertAttribute name="body"/></td>
+  </tr>
+</table>           
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layout_list.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layout_list.jsp
new file mode 100644
index 000000000..b34569090
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layout_list.jsp
@@ -0,0 +1,43 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
+
+<table  border="2"  width="300"  bordercolor="Gray">
+  <tr>
+    <td  bgcolor="Blue"><strong><tiles:getAsString name="title"/></strong></td>
+  </tr>
+  <tr>
+    <td><tiles:insertAttribute name="header"/></td>
+  </tr>
+  <tr>
+    <td>
+        <tiles:importAttribute name="list"/>
+        <c:forEach var="attribute" items="${list}">
+            <tiles:insertAttribute value="${attribute}" />
+        </c:forEach>
+    </td>
+  </tr>
+</table>           
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layout_nobody.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layout_nobody.jsp
new file mode 100644
index 000000000..42f115287
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layout_nobody.jsp
@@ -0,0 +1,34 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<table  border="2"  width="300"  bordercolor="Gray">
+  <tr>
+    <td  bgcolor="Blue"><strong><tiles:getAsString name="title"/></strong></td>
+  </tr>
+  <tr>
+    <td><tiles:insertAttribute name="header"/></td>
+  </tr>
+</table>           
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layout_override.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layout_override.jsp
new file mode 100644
index 000000000..074c980ef
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layout_override.jsp
@@ -0,0 +1,40 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<table  border="2"  width="300"  bordercolor="Gray">
+  <tr>
+    <td  bgcolor="Green"><strong>This is the overridden template.</strong></td>
+  </tr>
+  <tr>
+    <td  bgcolor="Blue"><strong><tiles:getAsString name="title"/></strong></td>
+  </tr>
+  <tr>
+    <td><tiles:insertAttribute name="header"/></td>
+  </tr>
+  <tr>
+    <td><tiles:insertAttribute name="body"/></td>
+  </tr>
+</table>           
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layout_preparer.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layout_preparer.jsp
new file mode 100644
index 000000000..44f24e8f1
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layout_preparer.jsp
@@ -0,0 +1,38 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<table  border="2"  width="300"  bordercolor="Gray">
+  <tr>
+    <td  bgcolor="Blue"><strong><tiles:getAsString name="title"/></strong></td>
+  </tr>
+  <tr>
+    <td><tiles:insertAttribute name="header"/></td>
+  </tr>
+  <tr>
+    <td><tiles:insertAttribute name="body"
+        preparer="org.apache.tiles.test.preparer.AttributeViewPreparer"/></td>
+  </tr>
+</table>           
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layout_roles.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layout_roles.jsp
new file mode 100644
index 000000000..44f43f2d5
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/layout_roles.jsp
@@ -0,0 +1,37 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<table  border="2"  width="300"  bordercolor="Gray">
+  <tr>
+    <td  bgcolor="Blue"><strong><tiles:getAsString name="title"/></strong></td>
+  </tr>
+  <tr>
+    <td><tiles:insertAttribute name="header" role="goodrole" /></td>
+  </tr>
+  <tr>
+    <td><tiles:insertAttribute name="body" role="badrole" /></td>
+  </tr>
+</table>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/override.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/override.jsp
new file mode 100644
index 000000000..9d7cda6f0
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/override.jsp
@@ -0,0 +1,25 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<div align="center"><b><i>This is an overridden content</i></b></div>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/putallattributeslayout.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/putallattributeslayout.jsp
new file mode 100644
index 000000000..38578615a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/putallattributeslayout.jsp
@@ -0,0 +1,35 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
+
+<tiles:importAttribute/>
+
+<c:out value="${one}"/>
+<ul>
+  <li><c:out value="${two}"/></li>
+  <li><c:out value="${three}"/></li>
+  <li><c:out value="${four}"/> </li>
+</ul>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/putattributeslayout.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/putattributeslayout.jsp
new file mode 100644
index 000000000..3c1fc7e22
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/putattributeslayout.jsp
@@ -0,0 +1,35 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
+<tiles:importAttribute name="stringTest"/>
+<tiles:importAttribute name="list"/>
+Single attribute "stringTest" value: <c:out value="${stringTest}" /> <br/><br/>
+The attribute "list" contains these values:
+<ul>
+<c:forEach var="item" items="${list}">
+<li><tiles:insertAttribute value="${item}" /></li>
+</c:forEach>
+</ul>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/selectlocale.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/selectlocale.jsp
new file mode 100644
index 000000000..66e9007e5
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/selectlocale.jsp
@@ -0,0 +1,45 @@
+<%@ page session="false" %>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Select your locale</title>
+</head>
+<body>
+<form action="servlets/selectLocaleServlet">
+Select your locale:
+<select name="locale">
+<option selected="selected" value="">Default</option>
+<option value="en_US">American English</option>
+<option value="en_GB">British English</option>
+<option value="fr_FR">French</option>
+<option value="it_IT">Italian</option>
+</select>
+<input type="submit" value="Submit" />
+</form>
+<div id="defaultLocaleMessage">Your default Locale is <%=request.getLocale().toString() %></div>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/selectlocale_db.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/selectlocale_db.jsp
new file mode 100644
index 000000000..9fbe02f9e
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/selectlocale_db.jsp
@@ -0,0 +1,45 @@
+<%@ page session="false" %>
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Select your locale</title>
+</head>
+<body>
+<form action="servlets/selectLocaleServletDb">
+Select your locale:
+<select name="locale">
+<option selected="selected" value="">Default</option>
+<option value="en_US">American English</option>
+<option value="en_GB">British English</option>
+<option value="fr_FR">French</option>
+<option value="it_IT">Italian</option>
+</select>
+<input type="submit" value="Submit" />
+</form>
+<div id="defaultLocaleMessage">Your default Locale is <%=request.getLocale().toString() %></div>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testdecorationfilter.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testdecorationfilter.jsp
new file mode 100644
index 000000000..2672fd46c
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testdecorationfilter.jsp
@@ -0,0 +1,25 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<i>This Content should be wrapped with the standard layout.</i>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testdef.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testdef.jsp
new file mode 100644
index 000000000..fb7b6056a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testdef.jsp
@@ -0,0 +1,32 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:definition name="templateDefinition" template="/layout.jsp">
+  <tiles:putAttribute name="title"  value="This is the title." />
+  <tiles:putAttribute name="header" value="/header.jsp" />
+  <tiles:putAttribute name="body"   value="/body.jsp" />
+</tiles:definition>
+<tiles:insertDefinition name="templateDefinition" />
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testdef_extend.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testdef_extend.jsp
new file mode 100644
index 000000000..4286480d6
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testdef_extend.jsp
@@ -0,0 +1,33 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:definition name="test.definition.override.one" extends="test.definition">
+  <tiles:putAttribute name="body"   value="/override.jsp" />
+</tiles:definition>
+<tiles:definition name="test.definition.override.two" extends="test.definition.override.one">
+  <tiles:putAttribute name="title"   value="This is an overridden title" />
+</tiles:definition>
+<tiles:insertDefinition name="test.definition.override.two" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testdef_list_inherit.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testdef_list_inherit.jsp
new file mode 100644
index 000000000..84f198250
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testdef_list_inherit.jsp
@@ -0,0 +1,33 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:definition name="templateDefinition" extends="test.putAttributes">
+  <tiles:putAttribute name="stringTest" value="This is a string" type="string"/>
+  <tiles:putListAttribute name="list" inherit="true">
+    <tiles:addAttribute value="valueFour" type="string" />
+  </tiles:putListAttribute>
+</tiles:definition>
+<tiles:insertDefinition name="templateDefinition" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testdef_preparer.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testdef_preparer.jsp
new file mode 100644
index 000000000..d1a5461fa
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testdef_preparer.jsp
@@ -0,0 +1,32 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:definition name="templateDefinition" template="/layout.jsp" preparer="org.apache.tiles.test.preparer.TestViewPreparer">
+  <tiles:putAttribute name="title"  value="This is the title." />
+  <tiles:putAttribute name="header" value="/header.jsp" />
+  <tiles:putAttribute name="body"   value="/body.jsp" />
+</tiles:definition>
+<tiles:insertDefinition name="templateDefinition" />
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testimportattribute.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testimportattribute.jsp
new file mode 100644
index 000000000..d54b37d34
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testimportattribute.jsp
@@ -0,0 +1,27 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertDefinition name="test.putAttributes" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testimportattribute_all.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testimportattribute_all.jsp
new file mode 100644
index 000000000..4633fcb44
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testimportattribute_all.jsp
@@ -0,0 +1,27 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertDefinition name="test.putAllAttributes" />
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testimportattribute_inherit.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testimportattribute_inherit.jsp
new file mode 100644
index 000000000..79f5988cc
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testimportattribute_inherit.jsp
@@ -0,0 +1,27 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertDefinition name="test.putAttributes.inherit" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition.jsp
new file mode 100644
index 000000000..02cb53321
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition.jsp
@@ -0,0 +1,27 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertDefinition name="test.definition" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_attribute_preparer.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_attribute_preparer.jsp
new file mode 100644
index 000000000..4d31a4c00
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_attribute_preparer.jsp
@@ -0,0 +1,27 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertDefinition name="test.definition.attribute.preparer" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_attribute_roles.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_attribute_roles.jsp
new file mode 100644
index 000000000..6f3064e2d
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_attribute_roles.jsp
@@ -0,0 +1,27 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertDefinition name="test.definition.roles" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_attribute_roles_tags.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_attribute_roles_tags.jsp
new file mode 100644
index 000000000..8c5c58c07
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_attribute_roles_tags.jsp
@@ -0,0 +1,27 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertDefinition name="test.definition.roles.tags" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_cascaded.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_cascaded.jsp
new file mode 100644
index 000000000..0137435ac
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_cascaded.jsp
@@ -0,0 +1,27 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertDefinition name="test.cascaded.definition" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_cascaded_list.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_cascaded_list.jsp
new file mode 100644
index 000000000..8018fb48f
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_cascaded_list.jsp
@@ -0,0 +1,27 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertDefinition name="test.cascaded.list.definition" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_cascaded_overridden.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_cascaded_overridden.jsp
new file mode 100644
index 000000000..192f99e99
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_cascaded_overridden.jsp
@@ -0,0 +1,27 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertDefinition name="test.overridden.cascaded.definition" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_cascaded_template.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_cascaded_template.jsp
new file mode 100644
index 000000000..9e579dfce
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_cascaded_template.jsp
@@ -0,0 +1,27 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertDefinition name="test.cascaded.template.definition" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_classpath.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_classpath.jsp
new file mode 100644
index 000000000..7ba57204f
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_classpath.jsp
@@ -0,0 +1,27 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertDefinition name="classpath.definition" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_composite.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_composite.jsp
new file mode 100644
index 000000000..a89b0e6ae
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_composite.jsp
@@ -0,0 +1,27 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertDefinition name="test.composite.definition" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_composite_tags.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_composite_tags.jsp
new file mode 100644
index 000000000..ade933003
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_composite_tags.jsp
@@ -0,0 +1,37 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:definition name="test.inner.definition.tags" template="/layout.jsp">
+    <tiles:putAttribute name="title"  value="This is an inner definition with tags."/>
+    <tiles:putAttribute name="header" value="/header.jsp"/>
+    <tiles:putAttribute name="body"   value="/body.jsp"/>
+</tiles:definition>
+<tiles:definition name="test.composite.definition.tags" template="/layout.jsp">
+    <tiles:putAttribute name="title"  value="This is a composite definition with tags."/>
+    <tiles:putAttribute name="header" value="/header.jsp"/>
+    <tiles:putAttribute name="body"   value="test.inner.definition.tags" type="definition"/>
+</tiles:definition>
+<tiles:insertDefinition name="test.composite.definition.tags" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_composite_tags_includes_configured.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_composite_tags_includes_configured.jsp
new file mode 100644
index 000000000..3ad4fbecc
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_composite_tags_includes_configured.jsp
@@ -0,0 +1,37 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:definition name="test.inner.definition.tags" template="/layout.jsp">
+    <tiles:putAttribute name="title"  value="This is an inner definition with tags."/>
+    <tiles:putAttribute name="header" value="/header.jsp"/>
+    <tiles:putAttribute name="body"   value="/body.jsp"/>
+</tiles:definition>
+<tiles:definition name="test.composite.definition.tags" template="/layout.jsp">
+    <tiles:putAttribute name="title"  value="This is a composite definition with tags."/>
+    <tiles:putAttribute name="header" value="/header.jsp"/>
+    <tiles:putAttribute name="body"   value="test.inner.definition" type="definition"/>
+</tiles:definition>
+<tiles:insertDefinition name="test.composite.definition.tags" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_composite_tags_includes_configured_notype.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_composite_tags_includes_configured_notype.jsp
new file mode 100644
index 000000000..804143df9
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_composite_tags_includes_configured_notype.jsp
@@ -0,0 +1,37 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:definition name="test.inner.definition.tags" template="/layout.jsp">
+    <tiles:putAttribute name="title"  value="This is an inner definition with tags."/>
+    <tiles:putAttribute name="header" value="/header.jsp"/>
+    <tiles:putAttribute name="body"   value="/body.jsp"/>
+</tiles:definition>
+<tiles:definition name="test.composite.definition.tags" template="/layout.jsp">
+    <tiles:putAttribute name="title"  value="This is a composite definition with tags."/>
+    <tiles:putAttribute name="header" value="/header.jsp"/>
+    <tiles:putAttribute name="body"   value="test.inner.definition"/>
+</tiles:definition>
+<tiles:insertDefinition name="test.composite.definition.tags" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_composite_tags_notype.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_composite_tags_notype.jsp
new file mode 100644
index 000000000..b2fbb0f6c
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_composite_tags_notype.jsp
@@ -0,0 +1,37 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:definition name="test.inner.definition.tags" template="/layout.jsp">
+    <tiles:putAttribute name="title"  value="This is an inner definition with tags."/>
+    <tiles:putAttribute name="header" value="/header.jsp"/>
+    <tiles:putAttribute name="body"   value="/body.jsp"/>
+</tiles:definition>
+<tiles:definition name="test.composite.definition.tags" template="/layout.jsp">
+    <tiles:putAttribute name="title"  value="This is a composite definition with tags."/>
+    <tiles:putAttribute name="header" value="/header.jsp"/>
+    <tiles:putAttribute name="body"   value="test.inner.definition.tags"/>
+</tiles:definition>
+<tiles:insertDefinition name="test.composite.definition.tags" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_db.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_db.jsp
new file mode 100644
index 000000000..41f96ed52
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_db.jsp
@@ -0,0 +1,28 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:setCurrentContainer containerKey="db"/>
+<tiles:insertDefinition name="test.definition" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_defaultvalues.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_defaultvalues.jsp
new file mode 100644
index 000000000..6514aefb0
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_defaultvalues.jsp
@@ -0,0 +1,27 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertDefinition name="test.defaultvalues.definition" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_el.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_el.jsp
new file mode 100644
index 000000000..077979142
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_el.jsp
@@ -0,0 +1,27 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertDefinition name="test.composite.el.definition" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_el_singleeval.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_el_singleeval.jsp
new file mode 100644
index 000000000..476ca17ee
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_el_singleeval.jsp
@@ -0,0 +1,27 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertDefinition name="test.composite.el.doNotShow.definition" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_exception.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_exception.jsp
new file mode 100644
index 000000000..12fd4b61e
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_exception.jsp
@@ -0,0 +1,27 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertDefinition name="test.definition.exception" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_extended_db.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_extended_db.jsp
new file mode 100644
index 000000000..e20a7547a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_extended_db.jsp
@@ -0,0 +1,28 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:setCurrentContainer containerKey="db"/>
+<tiles:insertDefinition name="test.definition.extended" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_flush.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_flush.jsp
new file mode 100644
index 000000000..91d851fb4
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_flush.jsp
@@ -0,0 +1,27 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertDefinition name="test.definition.flush" flush="true"/>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_freemarker.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_freemarker.jsp
new file mode 100644
index 000000000..0243922a6
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_freemarker.jsp
@@ -0,0 +1,27 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertDefinition name="test.definition.freemarker" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_ignore.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_ignore.jsp
new file mode 100644
index 000000000..8304d69ef
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_ignore.jsp
@@ -0,0 +1,27 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertDefinition name="test.definition.ignore" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_inline.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_inline.jsp
new file mode 100644
index 000000000..c3fe96fdf
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_inline.jsp
@@ -0,0 +1,31 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertDefinition name="test.definition">
+  <tiles:putAttribute name="body">
+  <div align="center"><b><i>This is an inline content</i></b></div>
+  </tiles:putAttribute>
+</tiles:insertDefinition>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_mvel.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_mvel.jsp
new file mode 100644
index 000000000..2451ace4c
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_mvel.jsp
@@ -0,0 +1,27 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertDefinition name="test.composite.mvel.definition" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_ognl.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_ognl.jsp
new file mode 100644
index 000000000..8d335be34
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_ognl.jsp
@@ -0,0 +1,27 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertDefinition name="test.composite.ognl.definition" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_old.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_old.jsp
new file mode 100644
index 000000000..2ae85f887
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_old.jsp
@@ -0,0 +1,27 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertDefinition name="test.definition.old_format" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_openbody.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_openbody.jsp
new file mode 100644
index 000000000..c8d45ab36
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_openbody.jsp
@@ -0,0 +1,27 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertDefinition name="test.openbody.definition" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_override.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_override.jsp
new file mode 100644
index 000000000..f41461783
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_override.jsp
@@ -0,0 +1,29 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertDefinition name="test.definition">
+  <tiles:putAttribute name="body"   value="/override.jsp" />
+</tiles:insertDefinition>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_override_and_not.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_override_and_not.jsp
new file mode 100644
index 000000000..af51da357
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_override_and_not.jsp
@@ -0,0 +1,32 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+Overridden content:<br/>
+<tiles:insertDefinition name="test.definition">
+  <tiles:putAttribute name="body"   value="/override.jsp" />
+</tiles:insertDefinition>
+<br/>
+Not overridden content:<br/>
+<tiles:insertDefinition name="test.definition" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_override_template.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_override_template.jsp
new file mode 100644
index 000000000..7a9b71b78
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_override_template.jsp
@@ -0,0 +1,27 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertDefinition name="test.definition" template="/layout_override.jsp" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_preparer.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_preparer.jsp
new file mode 100644
index 000000000..8d1300f49
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_preparer.jsp
@@ -0,0 +1,27 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertDefinition name="preparer.definition" preparer="org.apache.tiles.test.preparer.TestViewPreparer" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_preparer_configured.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_preparer_configured.jsp
new file mode 100644
index 000000000..67ab55ac4
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_preparer_configured.jsp
@@ -0,0 +1,27 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertDefinition name="preparer.definition.configured"/>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_regexp.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_regexp.jsp
new file mode 100644
index 000000000..66ca8512b
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_regexp.jsp
@@ -0,0 +1,28 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+<tiles:setCurrentContainer containerKey="alternate" />
+<tiles:insertDefinition name="test.regexp.definitionOne.messageHello" />
+<tiles:insertDefinition name="test.regexp.definitionTwo.messageBye" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_reversed.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_reversed.jsp
new file mode 100644
index 000000000..362a3630f
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_reversed.jsp
@@ -0,0 +1,27 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertDefinition name="test.reversed.definition" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_role.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_role.jsp
new file mode 100644
index 000000000..2551f8505
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_role.jsp
@@ -0,0 +1,28 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertDefinition name="test.definition.appears.configured" />
+<tiles:insertDefinition name="test.definition.does_not_appear.configured" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_role_tag.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_role_tag.jsp
new file mode 100644
index 000000000..6b632aa1b
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_role_tag.jsp
@@ -0,0 +1,28 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertDefinition name="test.definition.appears" role="goodrole" />
+<tiles:insertDefinition name="test.definition.does_not_appear" role="badrole" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_wildcard.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_wildcard.jsp
new file mode 100644
index 000000000..9128c3ae7
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinition_wildcard.jsp
@@ -0,0 +1,28 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+<tiles:setCurrentContainer containerKey="alternate" />
+<tiles:insertDefinition name="test.definitionOne.messageHello" />
+<tiles:insertDefinition name="test.definitionTwo.messageBye" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinitionexpr.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinitionexpr.jsp
new file mode 100644
index 000000000..c29631429
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertdefinitionexpr.jsp
@@ -0,0 +1,27 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertDefinition name="test.definition.expr" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertnesteddefinition.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertnesteddefinition.jsp
new file mode 100644
index 000000000..eef3bb32b
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertnesteddefinition.jsp
@@ -0,0 +1,27 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertDefinition name="test.nesting.definitions" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertnesteddefinition_tags.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertnesteddefinition_tags.jsp
new file mode 100644
index 000000000..1727d39b8
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertnesteddefinition_tags.jsp
@@ -0,0 +1,38 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:definition name="test.nesting.definitions.tags" template="/layout.jsp">
+    <tiles:putAttribute name="title"  value="This is the title."/>
+    <tiles:putAttribute name="header" value="/header.jsp"/>
+    <tiles:putAttribute name="body">
+        <tiles:definition template="/layout.jsp">
+            <tiles:putAttribute name="title"  value="This is a nested definition."/>
+            <tiles:putAttribute name="header" value="/header.jsp"/>
+            <tiles:putAttribute name="body"   value="/body.jsp"/>
+        </tiles:definition>
+    </tiles:putAttribute>
+</tiles:definition>
+<tiles:insertDefinition name="test.nesting.definitions.tags" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertnestedlistdefinition.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertnestedlistdefinition.jsp
new file mode 100644
index 000000000..cebe125ba
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertnestedlistdefinition.jsp
@@ -0,0 +1,27 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertDefinition name="test.nesting.list.definitions" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertnestedlistdefinition_tags.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertnestedlistdefinition_tags.jsp
new file mode 100644
index 000000000..ef5f1be75
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testinsertnestedlistdefinition_tags.jsp
@@ -0,0 +1,40 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:definition name="test.nesting.definitions.tags" template="/layout_list.jsp">
+    <tiles:putAttribute name="title"  value="This is the title."/>
+    <tiles:putAttribute name="header" value="/header.jsp"/>
+    <tiles:putListAttribute name="list">
+        <tiles:addAttribute>
+	        <tiles:definition template="/layout.jsp">
+	            <tiles:putAttribute name="title"  value="This is a nested definition."/>
+	            <tiles:putAttribute name="header" value="/header.jsp"/>
+	            <tiles:putAttribute name="body"   value="/body.jsp"/>
+	        </tiles:definition>
+        </tiles:addAttribute>
+    </tiles:putListAttribute>
+</tiles:definition>
+<tiles:insertDefinition name="test.nesting.definitions.tags" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testput.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testput.jsp
new file mode 100644
index 000000000..8f158fce8
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testput.jsp
@@ -0,0 +1,31 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertTemplate template="/layout.jsp">
+  <tiles:putAttribute name="title"  value="This is the title." />
+  <tiles:putAttribute name="header" value="/header.jsp" />
+  <tiles:putAttribute name="body"   value="/body.jsp" />
+</tiles:insertTemplate>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testput_cascaded.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testput_cascaded.jsp
new file mode 100644
index 000000000..fca4dc38c
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testput_cascaded.jsp
@@ -0,0 +1,31 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertTemplate template="/layout.jsp">
+  <tiles:putAttribute name="title"  value="This is the title." cascade="true" />
+  <tiles:putAttribute name="header" value="/header.jsp" cascade="true" />
+  <tiles:putAttribute name="body"   value="test.inner.cascadable.definition" />
+</tiles:insertTemplate>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testput_cascaded_overridden.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testput_cascaded_overridden.jsp
new file mode 100644
index 000000000..ce4fe372a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testput_cascaded_overridden.jsp
@@ -0,0 +1,31 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertTemplate template="/layout.jsp">
+  <tiles:putAttribute name="title"  value="This is the title." cascade="true" />
+  <tiles:putAttribute name="header" value="/alternate-header.jsp" cascade="true" />
+  <tiles:putAttribute name="body"   value="test.inner.definition" />
+</tiles:insertTemplate>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testput_cascaded_template.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testput_cascaded_template.jsp
new file mode 100644
index 000000000..d92fc7253
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testput_cascaded_template.jsp
@@ -0,0 +1,31 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertTemplate template="/layout.jsp">
+  <tiles:putAttribute name="title"  value="This is the title." cascade="true" />
+  <tiles:putAttribute name="header" value="/header.jsp" cascade="true" />
+  <tiles:putAttribute name="body"   value="/layout_nobody.jsp" />
+</tiles:insertTemplate>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testput_el.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testput_el.jsp
new file mode 100644
index 000000000..21bf428a2
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testput_el.jsp
@@ -0,0 +1,34 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<c:set var="bodyContent" value="Body Content defined by and el" />
+
+<tiles:insertTemplate template="/layout.jsp">
+  <tiles:putAttribute name="title"  value="This is the title." />
+  <tiles:putAttribute name="header" value="/header.jsp" />
+  <tiles:putAttribute name="body"   value="${bodyContent}" />
+</tiles:insertTemplate>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testput_el_singleeval.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testput_el_singleeval.jsp
new file mode 100644
index 000000000..6fc19a518
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testput_el_singleeval.jsp
@@ -0,0 +1,35 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<c:set var="doNotShowBody" value="${'${'}requestScope.doNotShow}" />
+<c:set var="doNotShow" scope="request" value="DO NOT SHOW!!!" />
+
+<tiles:insertTemplate template="/layout.jsp">
+  <tiles:putAttribute name="title"  value="This is the title." />
+  <tiles:putAttribute name="header" value="/header.jsp" />
+  <tiles:putAttribute name="body"   value="${doNotShowBody}" />
+</tiles:insertTemplate>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testput_flush.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testput_flush.jsp
new file mode 100644
index 000000000..2cdca88e5
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testput_flush.jsp
@@ -0,0 +1,31 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertTemplate template="/layout.jsp" flush="true">
+  <tiles:putAttribute name="title"  value="This is the title." />
+  <tiles:putAttribute name="header" value="/header.jsp" />
+  <tiles:putAttribute name="body"   value="/body.jsp" />
+</tiles:insertTemplate>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testput_reversed.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testput_reversed.jsp
new file mode 100644
index 000000000..468049787
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testput_reversed.jsp
@@ -0,0 +1,31 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertTemplate template="/layout_alt_title.jsp">
+  <tiles:putAttribute name="title"  value="This is the title." type="reversed" />
+  <tiles:putAttribute name="header" value="/header.jsp" />
+  <tiles:putAttribute name="body"   value="/body.jsp" />
+</tiles:insertTemplate>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testput_servlet.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testput_servlet.jsp
new file mode 100644
index 000000000..0f02634e4
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testput_servlet.jsp
@@ -0,0 +1,31 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertTemplate template="/servlets/layoutServlet">
+  <tiles:putAttribute name="title"  value="This is the title." />
+  <tiles:putAttribute name="header" value="/header.jsp" />
+  <tiles:putAttribute name="body"   value="/body.jsp" />
+</tiles:insertTemplate>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testputlist.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testputlist.jsp
new file mode 100644
index 000000000..0e0239c35
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testputlist.jsp
@@ -0,0 +1,34 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertTemplate template="/putattributeslayout.jsp">
+  <tiles:putAttribute name="stringTest" value="This is a string" type="string" />
+  <tiles:putListAttribute name="list">
+    <tiles:addAttribute value="valueOne" type="string" />
+    <tiles:addAttribute value="valueTwo" type="string" />
+    <tiles:addAttribute value="valueThree" type="string" />
+  </tiles:putListAttribute>
+</tiles:insertTemplate>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testputlist_cascaded.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testputlist_cascaded.jsp
new file mode 100644
index 000000000..eb1ed9843
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testputlist_cascaded.jsp
@@ -0,0 +1,37 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertTemplate template="/layout.jsp">
+  <tiles:putAttribute name="title"  value="This is the title." />
+  <tiles:putAttribute name="header" value="/header.jsp" />
+  <tiles:putAttribute name="body"   value="/putattributeslayout.jsp" />
+  <tiles:putAttribute name="stringTest" value="This is a string" type="string" cascade="true" />
+  <tiles:putListAttribute name="list" cascade="true">
+    <tiles:addAttribute value="valueOne" type="string" />
+    <tiles:addAttribute value="valueTwo" type="string" />
+    <tiles:addAttribute value="valueThree" type="string" />
+  </tiles:putListAttribute>
+</tiles:insertTemplate>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testputlist_inherit.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testputlist_inherit.jsp
new file mode 100644
index 000000000..9fe2fcc69
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testputlist_inherit.jsp
@@ -0,0 +1,31 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertDefinition name="test.putAttributes">
+  <tiles:putListAttribute name="list" inherit="true">
+    <tiles:addAttribute value="valueFour" type="string" />
+  </tiles:putListAttribute>
+</tiles:insertDefinition>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testsetcurrentcontainer.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testsetcurrentcontainer.jsp
new file mode 100644
index 000000000..83b554ee9
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testsetcurrentcontainer.jsp
@@ -0,0 +1,29 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+<tiles:setCurrentContainer containerKey="alternate" />
+<tiles:insertDefinition name="test.definition" />
+<tiles:setCurrentContainer />
+<tiles:insertDefinition name="test.definition" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testunderscores_nolocale.jsp b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testunderscores_nolocale.jsp
new file mode 100644
index 000000000..037beeb21
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/testunderscores_nolocale.jsp
@@ -0,0 +1,27 @@
+<%@ page session="false" %>
+<%--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+--%>
+<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>
+
+<tiles:insertDefinition name="test.non.localized.definition" />
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/alternate-header.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/alternate-header.vm
new file mode 100644
index 000000000..d96bf14af
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/alternate-header.vm
@@ -0,0 +1,23 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+<strong>This is the alternate header</strong>
+    
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/body.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/body.vm
new file mode 100644
index 000000000..d15a75cb6
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/body.vm
@@ -0,0 +1,22 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+<div align="center"><b><i>This is a body</i></b></div>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/classpath.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/classpath.vm
new file mode 100644
index 000000000..9aa751eb3
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/classpath.vm
@@ -0,0 +1,22 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+<div align="center"><b><i>This tile was loaded from the classpath</i></b></div>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/defaultlocale.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/defaultlocale.vm
new file mode 100644
index 000000000..9ce82fe24
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/defaultlocale.vm
@@ -0,0 +1,25 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+<div align="center"><b><i>
+<div id="defaultLocaleMessage">Your default Locale is $request.locale</div>
+</i></b></div>
+<a href="../selectlocale.vm">Select another locale</a>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/errorInclude.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/errorInclude.vm
new file mode 100644
index 000000000..d83598271
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/errorInclude.vm
@@ -0,0 +1,22 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+The "force include" attribute has not been set.
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/exception.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/exception.vm
new file mode 100644
index 000000000..8b6397964
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/exception.vm
@@ -0,0 +1,23 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+<strong>This throws an exception</strong>
+$exc.throwRuntimeException()
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/header.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/header.vm
new file mode 100644
index 000000000..fecafaa87
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/header.vm
@@ -0,0 +1,23 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+<strong>This is the header</strong>
+    
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/layout.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/layout.vm
new file mode 100644
index 000000000..fe392770f
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/layout.vm
@@ -0,0 +1,32 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+<table  border="2"  width="300"  bordercolor="Gray">
+  <tr>
+    <td  bgcolor="Blue"><strong>#tiles_getAsString({"name":"title"})#end</strong></td>
+  </tr>
+  <tr>
+    <td>#tiles_insertAttribute({"name":"header"})#end</td>
+  </tr>
+  <tr>
+    <td>#tiles_insertAttribute({"name":"body"})#end</td>
+  </tr>
+</table>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/layoutOne.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/layoutOne.vm
new file mode 100644
index 000000000..25b6a3a08
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/layoutOne.vm
@@ -0,0 +1,35 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+<table  border="2"  width="300"  bordercolor="Gray">
+  <tr>
+    <td  bgcolor="yellow">This is layout one.</td>
+  </tr>
+  <tr>
+    <td  bgcolor="Blue"><strong>#tiles_getAsString({"name":"title"})#end</strong></td>
+  </tr>
+  <tr>
+    <td>#tiles_insertAttribute({"name":"header"})#end</td>
+  </tr>
+  <tr>
+    <td>#tiles_insertAttribute({"name":"body"})#end</td>
+  </tr>
+</table>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/layoutTwo.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/layoutTwo.vm
new file mode 100644
index 000000000..cd094101d
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/layoutTwo.vm
@@ -0,0 +1,35 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+<table  border="2"  width="300"  bordercolor="Gray">
+  <tr>
+    <td  bgcolor="yellow">This is layout two.</td>
+  </tr>
+  <tr>
+    <td  bgcolor="Blue"><strong>#tiles_getAsString({"name":"title"})#end</strong></td>
+  </tr>
+  <tr>
+    <td>#tiles_insertAttribute({"name":"header"})#end</td>
+  </tr>
+  <tr>
+    <td>#tiles_insertAttribute({"name":"body"})#end</td>
+  </tr>
+</table>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/layout_alt_title.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/layout_alt_title.vm
new file mode 100644
index 000000000..13b795847
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/layout_alt_title.vm
@@ -0,0 +1,32 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+<table  border="2"  width="300"  bordercolor="Gray">
+  <tr>
+    <td  bgcolor="Blue"><strong>#tiles_insertAttribute({"name":"title"})#end</strong></td>
+  </tr>
+  <tr>
+    <td>#tiles_insertAttribute({"name":"header"})#end</td>
+  </tr>
+  <tr>
+    <td>#tiles_insertAttribute({"name":"body"})#end</td>
+  </tr>
+</table>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/layout_closebody.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/layout_closebody.vm
new file mode 100644
index 000000000..25974d9ea
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/layout_closebody.vm
@@ -0,0 +1,38 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+<table  border="2"  width="300"  bordercolor="Gray">
+  <tr>
+    <td  bgcolor="Blue"><strong>#tiles_getAsString({"name":"title"})#end</strong></td>
+  </tr>
+  <tr>
+    <td>#tiles_insertAttribute({"name":"header"})#end</td>
+  </tr>
+  <tr>
+    <td>
+    #tiles_insertAttribute({"name":"body"})
+        #tiles_putAttribute({"name":"title", "value":"This is a customized context"})#end
+        #tiles_putAttribute({"name":"header", "value":"/velocity/header.vm", "type":"velocity"})#end
+        #tiles_putAttribute({"name":"body", "value":"/velocity/body.vm", "type":"velocity"})#end
+    #end
+    </td>
+  </tr>
+</table>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/layout_default.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/layout_default.vm
new file mode 100644
index 000000000..69e5cbcba
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/layout_default.vm
@@ -0,0 +1,32 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+<table  border="2"  width="300"  bordercolor="Gray">
+  <tr>
+    <td  bgcolor="Blue"><strong>#tiles_insertAttribute({"name":"title", "defaultValue":"This is the default title."})#end</strong></td>
+  </tr>
+  <tr>
+    <td>#tiles_insertAttribute({"name":"header", "defaultValue":"alternate-header.vm", "defaultValueType":"template"})#end</td>
+  </tr>
+  <tr>
+    <td>#tiles_insertAttribute({"name":"body", "defaultValue":"This is the default body in the tag."})#end</td>
+  </tr>
+</table>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/layout_flush.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/layout_flush.vm
new file mode 100644
index 000000000..7cb87956f
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/layout_flush.vm
@@ -0,0 +1,32 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+<table  border="2"  width="300"  bordercolor="Gray">
+  <tr>
+    <td  bgcolor="Blue"><strong>#tiles_getAsString({"name":"title"})#end</strong></td>
+  </tr>
+  <tr>
+    <td>#tiles_insertAttribute({"name":"header", "flush":true})#end</td>
+  </tr>
+  <tr>
+    <td>#tiles_insertAttribute({"name":"body", "flush":true})#end</td>
+  </tr>
+</table>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/layout_ignore.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/layout_ignore.vm
new file mode 100644
index 000000000..4a5f2eff5
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/layout_ignore.vm
@@ -0,0 +1,32 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+<table  border="2"  width="300"  bordercolor="Gray">
+  <tr>
+    <td  bgcolor="Blue"><strong>#tiles_getAsString({"name":"title"})#end</strong></td>
+  </tr>
+  <tr>
+    <td>#tiles_insertAttribute({"name":"header", "ignore":true})#end</td>
+  </tr>
+  <tr>
+    <td>#tiles_insertAttribute({"name":"body"})#end</td>
+  </tr>
+</table>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/layout_list.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/layout_list.vm
new file mode 100644
index 000000000..fa73b274f
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/layout_list.vm
@@ -0,0 +1,37 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+<table  border="2"  width="300"  bordercolor="Gray">
+  <tr>
+    <td  bgcolor="Blue"><strong>#tiles_getAsString({"name":"title"})#end</strong></td>
+  </tr>
+  <tr>
+    <td>#tiles_insertAttribute({"name":"header"})#end</td>
+  </tr>
+  <tr>
+    <td>
+        #tiles_importAttribute({"name":"list"})
+        #foreach($attribute in $list)
+            #tiles_insertAttribute({"value":$attribute})#end
+        #end
+    </td>
+  </tr>
+</table>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/layout_nobody.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/layout_nobody.vm
new file mode 100644
index 000000000..d3b5dc0b4
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/layout_nobody.vm
@@ -0,0 +1,29 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+<table  border="2"  width="300"  bordercolor="Gray">
+  <tr>
+    <td  bgcolor="Blue"><strong>#tiles_getAsString({"name":"title"})#end</strong></td>
+  </tr>
+  <tr>
+    <td>#tiles_insertAttribute({"name":"header"})#end</td>
+  </tr>
+</table>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/layout_override.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/layout_override.vm
new file mode 100644
index 000000000..4bdcac15a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/layout_override.vm
@@ -0,0 +1,35 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+<table  border="2"  width="300"  bordercolor="Gray">
+  <tr>
+    <td  bgcolor="Green"><strong>This is the overridden template.</strong></td>
+  </tr>
+  <tr>
+    <td  bgcolor="Blue"><strong>#tiles_getAsString({"name":"title"})#end</strong></td>
+  </tr>
+  <tr>
+    <td>#tiles_insertAttribute({"name":"header"})#end</td>
+  </tr>
+  <tr>
+    <td>#tiles_insertAttribute({"name":"body"})#end</td>
+  </tr>
+</table>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/layout_preparer.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/layout_preparer.vm
new file mode 100644
index 000000000..45a93d7f2
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/layout_preparer.vm
@@ -0,0 +1,33 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+<table  border="2"  width="300"  bordercolor="Gray">
+  <tr>
+    <td  bgcolor="Blue"><strong>#tiles_getAsString({"name":"title"})#end</strong></td>
+  </tr>
+  <tr>
+    <td>#tiles_insertAttribute({"name":"header"})#end</td>
+  </tr>
+  <tr>
+    <td>#tiles_insertAttribute({"name":"body",
+        "preparer":"org.apache.tiles.test.preparer.AttributeViewPreparer"})#end</td>
+  </tr>
+</table>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/layout_roles.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/layout_roles.vm
new file mode 100644
index 000000000..76e7aa28b
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/layout_roles.vm
@@ -0,0 +1,32 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+<table  border="2"  width="300"  bordercolor="Gray">
+  <tr>
+    <td  bgcolor="Blue"><strong>#tiles_getAsString({"name":"title"})#end</strong></td>
+  </tr>
+  <tr>
+    <td>#tiles_insertAttribute({"name":"header", "role":"goodrole"})#end</td>
+  </tr>
+  <tr>
+    <td>#tiles_insertAttribute({"name":"body", "role":"badrole"})#end</td>
+  </tr>
+</table>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/override.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/override.vm
new file mode 100644
index 000000000..b936e87b2
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/override.vm
@@ -0,0 +1,22 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+<div align="center"><b><i>This is an overridden content</i></b></div>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/putallattributeslayout.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/putallattributeslayout.vm
new file mode 100644
index 000000000..461d008f5
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/putallattributeslayout.vm
@@ -0,0 +1,29 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_importAttribute({})
+
+${one}
+<ul>
+  <li>${two}</li>
+  <li>${three}</li>
+  <li>${four}</li>
+</ul>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/putattributeslayout.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/putattributeslayout.vm
new file mode 100644
index 000000000..fe563bfa6
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/putattributeslayout.vm
@@ -0,0 +1,30 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_importAttribute({"name":"stringTest"})
+#tiles_importAttribute({"name":"list"})
+Single attribute "stringTest" value: $esc.html($stringTest) <br/><br/>
+The attribute "list" contains these values:
+<ul>
+#foreach($item in $list)
+<li>#tiles_insertAttribute({"value":$item})#end</li>
+#end
+</ul>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/selectlocale.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/selectlocale.vm
new file mode 100644
index 000000000..f98aaaeb2
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/selectlocale.vm
@@ -0,0 +1,42 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Select your locale</title>
+</head>
+<body>
+<form action="servlets/selectLocaleServlet">
+Select your locale:
+<select name="locale">
+<option selected="selected" value="">Default</option>
+<option value="en_US">American English</option>
+<option value="en_GB">British English</option>
+<option value="fr_FR">French</option>
+<option value="it_IT">Italian</option>
+</select>
+<input type="submit" value="Submit" />
+</form>
+<div id="defaultLocaleMessage">Your default Locale is ${request.locale}</div>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testdecorationfilter.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testdecorationfilter.vm
new file mode 100644
index 000000000..d10c4388c
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testdecorationfilter.vm
@@ -0,0 +1,22 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+<i>This Content should be wrapped with the standard layout.</i>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testdef.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testdef.vm
new file mode 100644
index 000000000..00bc5d6dc
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testdef.vm
@@ -0,0 +1,27 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_definition({"name":"templateDefinition", "template":"/velocity/layout.vm"})
+  #tiles_putAttribute({"name":"title", "value":"This is the title."})#end
+  #tiles_putAttribute({"name":"header", "value":"/velocity/header.vm", "type":"velocity"})#end
+  #tiles_putAttribute({"name":"body", "value":"/velocity/body.vm", "type":"velocity"})#end
+#end
+#tiles_insertDefinition({"name":"templateDefinition"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testdef_extend.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testdef_extend.vm
new file mode 100644
index 000000000..c21cc0157
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testdef_extend.vm
@@ -0,0 +1,28 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_definition({"name":"test.definition.override.one", "extends":"velocity.test.definition"})
+  #tiles_putAttribute({"name":"body", "value":"/velocity/override.vm", "type":"velocity"})#end
+#end
+#tiles_definition({"name":"test.definition.override.two", "extends":"test.definition.override.one"})
+  #tiles_putAttribute({"name":"title", "value":"This is an overridden title"})#end
+#end
+#tiles_insertDefinition({"name":"test.definition.override.two"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testdef_list_inherit.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testdef_list_inherit.vm
new file mode 100644
index 000000000..59705fa00
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testdef_list_inherit.vm
@@ -0,0 +1,28 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_definition({"name":"templateDefinition", "extends":"test.putAttributes"})
+  #tiles_putAttribute({"name":"stringTest", "value":"This is a string", "type":"string"})#end
+  #tiles_putListAttribute({"name":"list", "inherit":true})
+    #tiles_addAttribute({"value":"valueFour", "type":"string"})#end
+  #end
+#end
+#tiles_insertDefinition({"name":"templateDefinition"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testdef_preparer.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testdef_preparer.vm
new file mode 100644
index 000000000..987628e44
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testdef_preparer.vm
@@ -0,0 +1,27 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_definition({"name":"templateDefinition", "template":"/velocity/layout.vm", "preparer":"org.apache.tiles.test.preparer.TestViewPreparer"})
+  #tiles_putAttribute({"name":"title", "value":"This is the title."})#end
+  #tiles_putAttribute({"name":"header", "value":"/velocity/header.vm", "type":"velocity"})#end
+  #tiles_putAttribute({"name":"body", "value":"/velocity/body.vm", "type":"velocity"})#end
+#end
+#tiles_insertDefinition({"name":"templateDefinition"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testimportattribute.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testimportattribute.vm
new file mode 100644
index 000000000..48dc8a507
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testimportattribute.vm
@@ -0,0 +1,22 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_insertDefinition({"name":"velocity.test.putAttributes"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testimportattribute_all.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testimportattribute_all.vm
new file mode 100644
index 000000000..008a3d779
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testimportattribute_all.vm
@@ -0,0 +1,22 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_insertDefinition({"name":"velocity.test.putAllAttributes"})#end
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testimportattribute_inherit.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testimportattribute_inherit.vm
new file mode 100644
index 000000000..163c1dd42
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testimportattribute_inherit.vm
@@ -0,0 +1,22 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_insertDefinition({"name":"velocity.test.putAttributes.inherit"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition.vm
new file mode 100644
index 000000000..c974ce937
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition.vm
@@ -0,0 +1,22 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_insertDefinition({"name" : "velocity.test.definition"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_attribute_preparer.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_attribute_preparer.vm
new file mode 100644
index 000000000..ff60d88ca
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_attribute_preparer.vm
@@ -0,0 +1,22 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_insertDefinition({"name":"velocity.test.definition.attribute.preparer"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_attribute_roles.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_attribute_roles.vm
new file mode 100644
index 000000000..31e82e35a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_attribute_roles.vm
@@ -0,0 +1,22 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_insertDefinition({"name":"velocity.test.definition.roles"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_attribute_roles_tags.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_attribute_roles_tags.vm
new file mode 100644
index 000000000..ca4f4fcc6
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_attribute_roles_tags.vm
@@ -0,0 +1,22 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_insertDefinition({"name":"velocity.test.definition.roles.tags"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_cascaded.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_cascaded.vm
new file mode 100644
index 000000000..81aec166d
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_cascaded.vm
@@ -0,0 +1,22 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_insertDefinition({"name":"velocity.test.cascaded.definition"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_cascaded_list.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_cascaded_list.vm
new file mode 100644
index 000000000..4e45bad00
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_cascaded_list.vm
@@ -0,0 +1,22 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_insertDefinition({"name":"velocity.test.cascaded.list.definition"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_cascaded_overridden.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_cascaded_overridden.vm
new file mode 100644
index 000000000..ce1c8de8f
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_cascaded_overridden.vm
@@ -0,0 +1,22 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_insertDefinition({"name":"velocity.test.overridden.cascaded.definition"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_cascaded_template.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_cascaded_template.vm
new file mode 100644
index 000000000..3148b5188
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_cascaded_template.vm
@@ -0,0 +1,22 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_insertDefinition({"name":"velocity.test.cascaded.template.definition"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_classpath.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_classpath.vm
new file mode 100644
index 000000000..8bb059495
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_classpath.vm
@@ -0,0 +1,22 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_insertDefinition({"name":"velocity.classpath.definition"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_composite.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_composite.vm
new file mode 100644
index 000000000..1e86d7def
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_composite.vm
@@ -0,0 +1,22 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_insertDefinition({"name":"velocity.test.composite.definition"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_composite_tags.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_composite_tags.vm
new file mode 100644
index 000000000..43a3120cb
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_composite_tags.vm
@@ -0,0 +1,32 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_definition({"name":"test.inner.definition.tags", "template":"/velocity/layout.vm"})
+    #tiles_putAttribute({"name":"title", "value":"This is an inner definition with tags."})#end
+    #tiles_putAttribute({"name":"header", "value":"/velocity/header.vm", "type":"velocity"})#end
+    #tiles_putAttribute({"name":"body", "value":"/velocity/body.vm", "type":"velocity"})#end
+#end
+#tiles_definition({"name":"test.composite.definition.tags", "template":"/velocity/layout.vm"})
+    #tiles_putAttribute({"name":"title", "value":"This is a composite definition with tags."})#end
+    #tiles_putAttribute({"name":"header", "value":"/velocity/header.vm", "type":"velocity"})#end
+    #tiles_putAttribute({"name":"body", "value":"test.inner.definition.tags", "type":"definition"})#end
+#end
+#tiles_insertDefinition({"name":"test.composite.definition.tags"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_composite_tags_includes_configured.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_composite_tags_includes_configured.vm
new file mode 100644
index 000000000..e2c0d697f
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_composite_tags_includes_configured.vm
@@ -0,0 +1,32 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_definition({"name":"test.inner.definition.tags", "template":"/velocity/layout.vm"})
+    #tiles_putAttribute({"name":"title", "value":"This is an inner definition with tags."})#end
+    #tiles_putAttribute({"name":"header", "value":"/velocity/header.vm", "type":"velocity"})#end
+    #tiles_putAttribute({"name":"body", "value":"/velocity/body.vm", "type":"velocity"})#end
+#end
+#tiles_definition({"name":"test.composite.definition.tags", "template":"/velocity/layout.vm"})
+    #tiles_putAttribute({"name":"title", "value":"This is a composite definition with tags."})#end
+    #tiles_putAttribute({"name":"header", "value":"/velocity/header.vm", "type":"velocity"})#end
+    #tiles_putAttribute({"name":"body", "value":"test.inner.definition", "type":"definition"})#end
+#end
+#tiles_insertDefinition({"name":"test.composite.definition.tags"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_composite_tags_includes_configured_notype.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_composite_tags_includes_configured_notype.vm
new file mode 100644
index 000000000..bc147e6f7
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_composite_tags_includes_configured_notype.vm
@@ -0,0 +1,32 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_definition({"name":"test.inner.definition.tags", "template":"/velocity/layout.vm"})
+    #tiles_putAttribute({"name":"title", "value":"This is an inner definition with tags."})#end
+    #tiles_putAttribute({"name":"header", "value":"/velocity/header.vm", "type":"velocity"})#end
+    #tiles_putAttribute({"name":"body", "value":"/velocity/body.vm", "type":"velocity"})#end
+#end
+#tiles_definition({"name":"test.composite.definition.tags", "template":"/velocity/layout.vm"})
+    #tiles_putAttribute({"name":"title", "value":"This is a composite definition with tags."})#end
+    #tiles_putAttribute({"name":"header", "value":"/velocity/header.vm", "type":"velocity"})#end
+    #tiles_putAttribute({"name":"body", "value":"test.inner.definition"})#end
+#end
+#tiles_insertDefinition({"name":"test.composite.definition.tags"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_composite_tags_notype.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_composite_tags_notype.vm
new file mode 100644
index 000000000..ecb5419ad
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_composite_tags_notype.vm
@@ -0,0 +1,31 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_definition({"name":"test.inner.definition.tags", "template":"/velocity/layout.vm"})
+    #tiles_putAttribute({"name":"title", "value":"This is an inner definition with tags."})#end
+    #tiles_putAttribute({"name":"header", "value":"/velocity/header.vm", "type":"velocity"})#end
+    #tiles_putAttribute({"name":"body", "value":"/velocity/body.vm", "type":"velocity"})#end
+#end
+#tiles_definition({"name":"test.composite.definition.tags", "template":"/velocity/layout.vm"})
+    #tiles_putAttribute({"name":"title", "value":"This is a composite definition with tags."})#end
+    #tiles_putAttribute({"name":"header", "value":"/velocity/header.vm", "type":"velocity"})#end
+    #tiles_putAttribute({"name":"body", "value":"test.inner.definition.tags"})#end
+#end
+#tiles_insertDefinition({"name":"test.composite.definition.tags"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_db.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_db.vm
new file mode 100644
index 000000000..83806c38f
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_db.vm
@@ -0,0 +1,23 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+$tiles.setCurrentContainer("db")
+#tiles_insertDefinition({"name":"test.definition"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_defaultvalues.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_defaultvalues.vm
new file mode 100644
index 000000000..3872fb29f
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_defaultvalues.vm
@@ -0,0 +1,22 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_insertDefinition({"name":"velocity.test.defaultvalues.definition"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_el.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_el.vm
new file mode 100644
index 000000000..81aed5504
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_el.vm
@@ -0,0 +1,22 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_insertDefinition({"name":"velocity.test.composite.el.definition"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_el_singleeval.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_el_singleeval.vm
new file mode 100644
index 000000000..45bf7790b
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_el_singleeval.vm
@@ -0,0 +1,22 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_insertDefinition({"name":"velocity.test.composite.el.doNotShow.definition"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_exception.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_exception.vm
new file mode 100644
index 000000000..89beea302
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_exception.vm
@@ -0,0 +1,22 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_insertDefinition({"name":"velocity.test.definition.exception"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_extended_db.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_extended_db.vm
new file mode 100644
index 000000000..b7ddf2a8c
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_extended_db.vm
@@ -0,0 +1,23 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+$tiles.setCurrentContainer("db")
+#tiles_insertDefinition({"name":"test.definition.extended"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_flush.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_flush.vm
new file mode 100644
index 000000000..203665b0f
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_flush.vm
@@ -0,0 +1,22 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_insertDefinition({"name":"velocity.test.definition.flush", "flush":true})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_ignore.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_ignore.vm
new file mode 100644
index 000000000..d46617016
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_ignore.vm
@@ -0,0 +1,22 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_insertDefinition({"name":"velocity.test.definition.ignore"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_inline.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_inline.vm
new file mode 100644
index 000000000..52c4a1e36
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_inline.vm
@@ -0,0 +1,26 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_insertDefinition({"name":"velocity.test.definition"})
+#tiles_putAttribute({"name":"body", "value":$inlineContent.toString()})
+  <div align="center"><b><i>This is an inline content</i></b></div>
+#end
+#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_mvel.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_mvel.vm
new file mode 100644
index 000000000..ed9b32f43
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_mvel.vm
@@ -0,0 +1,22 @@
+#*
+ * $Id: testinsertdefinition_el.vm 782137 2009-06-05 21:18:52Z apetrelli $
+ *
+ * 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.
+ *
+ *#
+#tiles_insertDefinition({"name":"velocity.test.composite.mvel.definition"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_ognl.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_ognl.vm
new file mode 100644
index 000000000..b3632479d
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_ognl.vm
@@ -0,0 +1,22 @@
+#*
+ * $Id: testinsertdefinition_el.vm 782137 2009-06-05 21:18:52Z apetrelli $
+ *
+ * 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.
+ *
+ *#
+#tiles_insertDefinition({"name":"velocity.test.composite.ognl.definition"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_old.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_old.vm
new file mode 100644
index 000000000..670146a37
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_old.vm
@@ -0,0 +1,22 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_insertDefinition({"name":"velocity.test.definition.old_format"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_openbody.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_openbody.vm
new file mode 100644
index 000000000..04c90e1b0
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_openbody.vm
@@ -0,0 +1,22 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_insertDefinition({"name":"velocity.test.openbody.definition"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_override.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_override.vm
new file mode 100644
index 000000000..7d9f2e76b
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_override.vm
@@ -0,0 +1,24 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_insertDefinition({"name":"velocity.test.definition"})
+  #tiles_putAttribute({"name":"body", "value":"/velocity/override.vm", "type":"velocity"})#end
+#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_override_and_not.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_override_and_not.vm
new file mode 100644
index 000000000..b534f4a80
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_override_and_not.vm
@@ -0,0 +1,28 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+Overridden content:<br/>
+#tiles_insertDefinition({"name":"velocity.test.definition"})
+  #tiles_putAttribute({"name":"body", "value":"/velocity/override.vm", "type":"velocity"})#end
+#end
+<br/>
+Not overridden content:<br/>
+#tiles_insertDefinition({"name":"velocity.test.definition"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_override_template.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_override_template.vm
new file mode 100644
index 000000000..3b0786fb0
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_override_template.vm
@@ -0,0 +1,22 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_insertDefinition({"name":"velocity.test.definition", "template":"/velocity/layout_override.vm"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_preparer.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_preparer.vm
new file mode 100644
index 000000000..ee13f078b
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_preparer.vm
@@ -0,0 +1,22 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_insertDefinition({"name":"velocity.preparer.definition", "preparer":"org.apache.tiles.test.preparer.TestViewPreparer"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_preparer_configured.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_preparer_configured.vm
new file mode 100644
index 000000000..61a162f1e
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_preparer_configured.vm
@@ -0,0 +1,22 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_insertDefinition({"name":"velocity.preparer.definition.configured"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_regexp.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_regexp.vm
new file mode 100644
index 000000000..45401b821
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_regexp.vm
@@ -0,0 +1,24 @@
+#*
+ * $Id: testinsertdefinition_wildcard.vm 782137 2009-06-05 21:18:52Z apetrelli $
+ *
+ * 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.
+ *
+ *#
+$tiles.setCurrentContainer("alternate")
+#tiles_insertDefinition({"name":"velocity.test.regexp.definitionOne.messageHello"})#end
+#tiles_insertDefinition({"name":"velocity.test.regexp.definitionTwo.messageBye"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_reversed.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_reversed.vm
new file mode 100644
index 000000000..72053ca82
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_reversed.vm
@@ -0,0 +1,22 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_insertDefinition({"name":"velocity.test.reversed.definition"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_role.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_role.vm
new file mode 100644
index 000000000..42015d559
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_role.vm
@@ -0,0 +1,23 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_insertDefinition({"name":"velocity.test.definition.appears.configured"})#end
+#tiles_insertDefinition({"name":"velocity.test.definition.does_not_appear.configured"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_role_tag.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_role_tag.vm
new file mode 100644
index 000000000..e29434c40
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_role_tag.vm
@@ -0,0 +1,23 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_insertDefinition({"name":"velocity.test.definition.appears", "role":"goodrole"})#end
+#tiles_insertDefinition({"name":"velocity.test.definition.does_not_appear", "role":"badrole"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_wildcard.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_wildcard.vm
new file mode 100644
index 000000000..955e7d5bc
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertdefinition_wildcard.vm
@@ -0,0 +1,24 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+$tiles.setCurrentContainer("alternate")
+#tiles_insertDefinition({"name":"velocity.test.definitionOne.messageHello"})#end
+#tiles_insertDefinition({"name":"velocity.test.definitionTwo.messageBye"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertnesteddefinition.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertnesteddefinition.vm
new file mode 100644
index 000000000..62b8d7b03
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertnesteddefinition.vm
@@ -0,0 +1,22 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_insertDefinition({"name":"velocity.test.nesting.definitions"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertnesteddefinition_tags.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertnesteddefinition_tags.vm
new file mode 100644
index 000000000..4dc3b0b3c
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertnesteddefinition_tags.vm
@@ -0,0 +1,33 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_definition({"name":"test.nesting.definitions.tags", "template":"/velocity/layout.vm"})
+    #tiles_putAttribute({"name":"title", "value":"This is the title."})#end
+    #tiles_putAttribute({"name":"header", "value":"/velocity/header.vm", "type":"velocity"})#end
+    #tiles_putAttribute({"name":"body"})
+        #tiles_definition({"template":"/velocity/layout.vm"})
+            #tiles_putAttribute({"name":"title", "value":"This is a nested definition."})#end
+            #tiles_putAttribute({"name":"header", "value":"/velocity/header.vm", "type":"velocity"})#end
+            #tiles_putAttribute({"name":"body", "value":"/velocity/body.vm", "type":"velocity"})#end
+        #end
+    #end
+#end
+#tiles_insertDefinition({"name":"test.nesting.definitions.tags"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertnestedlistdefinition.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertnestedlistdefinition.vm
new file mode 100644
index 000000000..1b0495b41
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertnestedlistdefinition.vm
@@ -0,0 +1,22 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_insertDefinition({"name":"velocity.test.nesting.list.definitions"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertnestedlistdefinition_tags.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertnestedlistdefinition_tags.vm
new file mode 100644
index 000000000..4a5fa975d
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testinsertnestedlistdefinition_tags.vm
@@ -0,0 +1,35 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_definition({"name":"test.nesting.definitions.tags", "template":"/velocity/layout_list.vm"})
+    #tiles_putAttribute({"name":"title", "value":"This is the title."})#end
+    #tiles_putAttribute({"name":"header", "value":"/velocity/header.vm", "type":"velocity"})#end
+    #tiles_putListAttribute({"name":"list"})
+        #tiles_addAttribute({})
+	        #tiles_definition({"template":"/velocity/layout.vm"})
+	            #tiles_putAttribute({"name":"title", "value":"This is a nested definition."})#end
+	            #tiles_putAttribute({"name":"header", "value":"/velocity/header.vm", "type":"velocity"})#end
+	            #tiles_putAttribute({"name":"body", "value":"/velocity/body.vm", "type":"velocity"})#end
+	        #end
+        #end
+    #end
+#end
+#tiles_insertDefinition({"name":"test.nesting.definitions.tags"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testput.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testput.vm
new file mode 100644
index 000000000..5e6b9572e
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testput.vm
@@ -0,0 +1,26 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_insertTemplate({"template":"/velocity/layout.vm"})
+  #tiles_putAttribute({"name":"title", "value":"This is the title."})#end
+  #tiles_putAttribute({"name":"header", "value":"/velocity/header.vm", "type":"velocity"})#end
+  #tiles_putAttribute({"name":"body", "value":"/velocity/body.vm", "type":"velocity"})#end
+#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testput_cascaded.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testput_cascaded.vm
new file mode 100644
index 000000000..67c52bd1f
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testput_cascaded.vm
@@ -0,0 +1,26 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_insertTemplate({"template":"/velocity/layout.vm"})
+  #tiles_putAttribute({"name":"title", "value":"This is the title.", "cascade":true})#end
+  #tiles_putAttribute({"name":"header", "value":"/velocity/header.vm", "type":"velocity", "cascade":true})#end
+  #tiles_putAttribute({"name":"body", "value":"test.inner.cascadable.definition"})#end
+#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testput_cascaded_overridden.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testput_cascaded_overridden.vm
new file mode 100644
index 000000000..53f4157e8
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testput_cascaded_overridden.vm
@@ -0,0 +1,26 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_insertTemplate({"template":"/velocity/layout.vm"})
+  #tiles_putAttribute({"name":"title", "value":"This is the title.", "cascade":true})#end
+  #tiles_putAttribute({"name":"header", "value":"/velocity/alternate-header.vm", "type":"velocity", "cascade":true})#end
+  #tiles_putAttribute({"name":"body", "value":"test.inner.definition"})#end
+#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testput_cascaded_template.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testput_cascaded_template.vm
new file mode 100644
index 000000000..0d1dcd95a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testput_cascaded_template.vm
@@ -0,0 +1,26 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_insertTemplate({"template":"/velocity/layout.vm"})
+  #tiles_putAttribute({"name":"title", "value":"This is the title.", "cascade":true})#end
+  #tiles_putAttribute({"name":"header", "value":"/velocity/header.vm", "type":"velocity", "cascade":true})#end
+  #tiles_putAttribute({"name":"body", "value":"/velocity/layout_nobody.vm", "type":"velocity"})#end
+#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testput_el.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testput_el.vm
new file mode 100644
index 000000000..9d6cf55df
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testput_el.vm
@@ -0,0 +1,28 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#set($bodyContent="Body Content defined by and el")
+
+#tiles_insertTemplate({"template":"/velocity/layout.vm"})
+  #tiles_putAttribute({"name":"title",  "value":"This is the title."})#end
+  #tiles_putAttribute({"name":"header", "value":"/velocity/header.vm", "type":"velocity"})#end
+  #tiles_putAttribute({"name":"body",   "value":$bodyContent})#end
+#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testput_el_singleeval.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testput_el_singleeval.vm
new file mode 100644
index 000000000..c79d2d64a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testput_el_singleeval.vm
@@ -0,0 +1,29 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#set($doNotShowBody="$" + "{" + "requestScope.doNotShow}")
+#set($doNotShow="DO NOT SHOW!!!")
+
+#tiles_insertTemplate({"template":"/velocity/layout.vm"})
+  #tiles_putAttribute({"name":"title", "value":"This is the title."})#end
+  #tiles_putAttribute({"name":"header", "value":"/velocity/header.vm", "type":"velocity"})#end
+  #tiles_putAttribute({"name":"body", "value":$doNotShowBody})#end
+#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testput_flush.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testput_flush.vm
new file mode 100644
index 000000000..4d418dfb7
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testput_flush.vm
@@ -0,0 +1,26 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_insertTemplate({"template":"/velocity/layout.vm", "flush":true})
+  #tiles_putAttribute({"name":"title",  "value":"This is the title."})#end
+  #tiles_putAttribute({"name":"header", "value":"/velocity/header.vm", "type":"velocity"})#end
+  #tiles_putAttribute({"name":"body",   "value":"/velocity/body.vm", "type":"velocity"})#end
+#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testput_reversed.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testput_reversed.vm
new file mode 100644
index 000000000..2f8ea2715
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testput_reversed.vm
@@ -0,0 +1,26 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_insertTemplate({"template":"/velocity/layout_alt_title.vm"})
+  #tiles_putAttribute({"name":"title", "value":"This is the title.", "type":"reversed"})#end
+  #tiles_putAttribute({"name":"header", "value":"/velocity/header.vm", "type":"velocity"})#end
+  #tiles_putAttribute({"name":"body", "value":"/velocity/body.vm", "type":"velocity"})#end
+#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testput_servlet.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testput_servlet.vm
new file mode 100644
index 000000000..9eeef1be7
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testput_servlet.vm
@@ -0,0 +1,26 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_insertTemplate({"template":"/servlets/layoutServlet"})
+  #tiles_putAttribute({"name":"title",  "value":"This is the title."})#end
+  #tiles_putAttribute({"name":"header", "value":"/velocity/header.vm", "type":"velocity"})#end
+  #tiles_putAttribute({"name":"body",   "value":"/velocity/body.vm", "type":"velocity"})#end
+#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testputlist.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testputlist.vm
new file mode 100644
index 000000000..fa8ababc7
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testputlist.vm
@@ -0,0 +1,29 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_insertTemplate({"template":"/velocity/putattributeslayout.vm"})
+  #tiles_putAttribute({"name":"stringTest", "value":"This is a string", "type":"string"})#end
+  #tiles_putListAttribute({"name":"list"})
+    #tiles_addAttribute({"value":"valueOne", "type":"string"})#end
+    #tiles_addAttribute({"value":"valueTwo", "type":"string"})#end
+    #tiles_addAttribute({"value":"valueThree", "type":"string"})#end
+  #end
+#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testputlist_cascaded.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testputlist_cascaded.vm
new file mode 100644
index 000000000..9810479bf
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testputlist_cascaded.vm
@@ -0,0 +1,32 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_insertTemplate({"template":"/velocity/layout.vm"})
+  #tiles_putAttribute({"name":"title", "value":"This is the title."})#end
+  #tiles_putAttribute({"name":"header", "value":"/velocity/header.vm", "type":"velocity"})#end
+  #tiles_putAttribute({"name":"body", "value":"/velocity/putattributeslayout.vm", "type":"velocity"})#end
+  #tiles_putAttribute({"name":"stringTest", "value":"This is a string", "type":"string", "cascade":true})#end
+  #tiles_putListAttribute({"name":"list", "cascade":true})
+    #tiles_addAttribute({"value":"valueOne", "type":"string"})#end
+    #tiles_addAttribute({"value":"valueTwo", "type":"string"})#end
+    #tiles_addAttribute({"value":"valueThree", "type":"string"})#end
+  #end
+#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testputlist_inherit.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testputlist_inherit.vm
new file mode 100644
index 000000000..d340d528b
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testputlist_inherit.vm
@@ -0,0 +1,26 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_insertDefinition({"name":"velocity.test.putAttributes"})
+  #tiles_putListAttribute({"name":"list", "inherit":true})
+    #tiles_addAttribute({"value":"valueFour", "type":"string"})#end
+  #end
+#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testsetcurrentcontainer.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testsetcurrentcontainer.vm
new file mode 100644
index 000000000..6d99a45f0
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testsetcurrentcontainer.vm
@@ -0,0 +1,25 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+$tiles.setCurrentContainer("alternate")
+#tiles_insertDefinition({"name":"velocity.test.definition"})#end
+$tiles.setCurrentContainer(null)
+#tiles_insertDefinition({"name":"velocity.test.definition"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testunderscores_nolocale.vm b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testunderscores_nolocale.vm
new file mode 100644
index 000000000..1a80d0ec0
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/main/webapp/velocity/testunderscores_nolocale.vm
@@ -0,0 +1,22 @@
+#*
+ * $Id$
+ *
+ * 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.
+ *
+ *#
+#tiles_insertDefinition({"name" : "velocity.test.non.localized.definition"})#end
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/site/site.xml b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/site/site.xml
new file mode 100644
index 000000000..c298bdfc6
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/site/site.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<project name="Apache Tiles - Test web application">
+     <skin>
+        <groupId>org.apache.maven.skins</groupId>
+        <artifactId>maven-fluido-skin</artifactId>
+        <version>1.3.0</version>
+     </skin>
+     <custom>
+        <fluidoSkin>
+        <topBarEnabled>true</topBarEnabled>
+        <sideBarEnabled>false</sideBarEnabled>
+        <searchEnabled>true</searchEnabled>
+        <gitHub>
+            <projectId>apache/tiles</projectId>
+            <ribbonOrientation>right</ribbonOrientation>
+            <ribbonColor>darkblue</ribbonColor>
+        </gitHub>
+        </fluidoSkin>
+     </custom>
+    <bannerLeft>
+        <name>Apache Tiles&#8482;</name>
+        <src>http://tiles.apache.org/images/logo.png</src>
+        <href>http://tiles.apache.org</href>
+    </bannerLeft>
+    <bannerRight>
+        <name>Apache Software Foundation</name>
+        <src>http://struts.apache.org/images/asf-logo.gif</src>
+        <href>http://www.apache.org</href>
+    </bannerRight>
+    <body>
+
+        <menu name="Apache Tiles&#8482;">
+            <item
+                   name="Welcome"
+                   href="../../index.html"/>
+            <item
+                    name="Tiles 3.0.x"
+                    href="../../framework/index.html"/>
+            <item
+                    name="Autotag 1.0.x"
+                    href="../../tiles-autotag/index.html"/>
+            <item
+                    name="Request 1.0.x"
+                    href="../../tiles-request/index.html"/>
+            <item
+                   name="Security bulletins"
+                   href="../security/index.html"/>
+            <item
+                   name="Download"
+                   href="http://tiles.apache.org/download.html"/>
+        </menu>
+
+        <menu ref="modules" />
+        <menu ref="reports" />
+
+        <footer>
+            <div class="row span12">
+                Apache Tiles, Tiles, Apache, the Apache feather logo, and the Apache Tiles
+                project logos are trademarks of The Apache Software Foundation.
+            </div>
+        </footer>
+    </body>
+</project>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/CompositeDefinitionWithInnerConfiguredDefinitionNoTypeTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/CompositeDefinitionWithInnerConfiguredDefinitionNoTypeTest.html
new file mode 100644
index 000000000..8e5542591
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/CompositeDefinitionWithInnerConfiguredDefinitionNoTypeTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Composite Definition with Inner Configured Definition with no Type Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Composite Definition with Inner Configured Definition with no Type Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Insert Definition that contains another definition inside (configured via tiles-defs.xml) using JSP tags without types</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a composite definition with tags.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a configured inner definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/CompositeDefinitionWithInnerConfiguredDefinitionTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/CompositeDefinitionWithInnerConfiguredDefinitionTest.html
new file mode 100644
index 000000000..14bd1ec65
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/CompositeDefinitionWithInnerConfiguredDefinitionTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Composite Definition with Inner Configured Definition Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Composite Definition with Inner Configured Definition Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Insert Definition that contains another definition inside (configured via tiles-defs.xml) using JSP tags</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a composite definition with tags.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a configured inner definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/CompositeDefinitionWithInnerDefinitionNoTypeTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/CompositeDefinitionWithInnerDefinitionNoTypeTest.html
new file mode 100644
index 000000000..68514e931
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/CompositeDefinitionWithInnerDefinitionNoTypeTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Composite Definition with Inner Configured Definition with no Type Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Composite Definition with Inner Configured Definition with no Type Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Insert Definition that contains another definition inside using JSP tags without types</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a composite definition with tags.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is an inner definition with tags.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/CompositeDefinitionWithInnerDefinitionTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/CompositeDefinitionWithInnerDefinitionTest.html
new file mode 100644
index 000000000..1a257b5ea
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/CompositeDefinitionWithInnerDefinitionTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Composite Definition with Inner Definition Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Composite Definition with Inner Definition Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Insert Definition that contains another definition inside using JSP tags</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a composite definition with tags.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is an inner definition with tags.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredCompositeDefinitionTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredCompositeDefinitionTest.html
new file mode 100644
index 000000000..fb58cfd77
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredCompositeDefinitionTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Composite Definition Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+w<tr><td rowspan="1" colspan="3">Configured Composite Definition Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Insert Configured Definition that contains another definition inside</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a configured composite definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a configured inner definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionAttributePreparerTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionAttributePreparerTest.html
new file mode 100644
index 000000000..89c60d675
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionAttributePreparerTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Attribute Preparer Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Attribute Preparer Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Insert Configured Definition with Attribute Preparer</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the value added by the AttributeViewPreparer</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionAttributeRolesTagsTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionAttributeRolesTagsTest.html
new file mode 100644
index 000000000..373529af7
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionAttributeRolesTagsTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Attribute Roles Tags Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Attribute Roles Tags Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Insert Configured Definition with Attribute that have Roles in Tags</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextNotPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionAttributeRolesTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionAttributeRolesTest.html
new file mode 100644
index 000000000..f365b1190
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionAttributeRolesTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Attribute Roles Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Attribute Roles Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Insert Configured Definition with Attribute that have Roles</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextNotPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionCascadedListTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionCascadedListTest.html
new file mode 100644
index 000000000..e7804f09c
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionCascadedListTest.html
@@ -0,0 +1,76 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Cascaded List Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Cascaded List Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Insert Configured Cascaded Definition with List</td>
+	<td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the title.</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the header</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>Single attribute "stringTest" value: This is a string </td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>valueOne</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>valueTwo</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>valueThree</td>
+    <td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionCascadedOverriddenTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionCascadedOverriddenTest.html
new file mode 100644
index 000000000..abf00c0bb
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionCascadedOverriddenTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Cascaded Overridden Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Cascaded Overridden Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Insert Configured Cascaded Definition with Override</td>
+	<td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the title.</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the header</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is a body</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is a configured inner definition.</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the header</td>
+    <td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionCascadedTemplateTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionCascadedTemplateTest.html
new file mode 100644
index 000000000..c6c540ec3
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionCascadedTemplateTest.html
@@ -0,0 +1,56 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Cascaded Template Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Cascaded Template Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Insert Configured Cascaded Definition with Template</td>
+	<td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the title.</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the header</td>
+    <td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionCascadedTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionCascadedTest.html
new file mode 100644
index 000000000..ca90ae5e4
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionCascadedTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Cascaded Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Cascaded Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Insert Configured Cascaded Definition</td>
+	<td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the title.</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the header</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is a body</td>
+    <td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionDbTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionDbTest.html
new file mode 100644
index 000000000..6ce38e343
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionDbTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Db Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Db Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Insert Configured Definition from DB</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionDefaultValuesTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionDefaultValuesTest.html
new file mode 100644
index 000000000..6c976a123
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionDefaultValuesTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition with Default Values Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition with Default Values Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Insert Configured Definition with Default Values</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the alternate header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the default body in the tag.</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionELSingleEvalTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionELSingleEvalTest.html
new file mode 100644
index 000000000..c2d88bf34
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionELSingleEvalTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition EL with Single Evaluation Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition EL with Single Evaluation Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Insert Configured Definition with EL to test Single Evaluation</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a configured definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>${requestScope.doNotShow}</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionELTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionELTest.html
new file mode 100644
index 000000000..f7cbbfa5f
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionELTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition EL Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition EL Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Insert Configured Definition with EL</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a configured composite definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a configured inner definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionExceptionTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionExceptionTest.html
new file mode 100644
index 000000000..153a1c5b8
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionExceptionTest.html
@@ -0,0 +1,51 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition with Exception Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Insert Configured Definition with an exception in an attribute page</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextNotPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionExprTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionExprTest.html
new file mode 100644
index 000000000..9b4d7fc97
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionExprTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition With Expression Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Insert Configured Definition With Expression</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionExtendedDbTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionExtendedDbTest.html
new file mode 100644
index 000000000..ecdc6999d
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionExtendedDbTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Extended Db Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Extended Db Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Insert Extended Configured Definition from DB</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is an extended definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionFlushTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionFlushTest.html
new file mode 100644
index 000000000..42d2ef63b
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionFlushTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition with Flush Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition with Flush Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Insert Configured Definition with Flush</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionFreeMarkerTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionFreeMarkerTest.html
new file mode 100644
index 000000000..91d31f246
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionFreeMarkerTest.html
@@ -0,0 +1,66 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Test with FreeMarker</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Test with FreeMarker</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Insert Configured Definition with FreeMarker</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This layout is made in FreeMarker.</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionFromClasspathTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionFromClasspathTest.html
new file mode 100644
index 000000000..57ffee93e
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionFromClasspathTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition from Classpath Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition from Classpath Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Insert Configured Classpath Definition</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This tile was loaded from the classpath</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionIgnoreTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionIgnoreTest.html
new file mode 100644
index 000000000..49c45b3af
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionIgnoreTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Ignore Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Ignore Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Insert Configured Definition with Ignore</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextNotPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionInlineTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionInlineTest.html
new file mode 100644
index 000000000..06bbe4ea6
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionInlineTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition with Inline Content Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition with Inline Content Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Insert Configured Definition with an inline content</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is an inline content</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionMVELTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionMVELTest.html
new file mode 100644
index 000000000..c0eaaebac
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionMVELTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition MVEL Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition MVEL Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Insert Configured Definition with MVEL</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a configured composite definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a configured inner definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionOGNLTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionOGNLTest.html
new file mode 100644
index 000000000..ba2b2d7a7
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionOGNLTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition OGNL Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition OGNL Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Insert Configured Definition with OGNL</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a configured composite definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a configured inner definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionOldFormatTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionOldFormatTest.html
new file mode 100644
index 000000000..0137c01ed
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionOldFormatTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Old Format Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Old Format Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Insert Configured Definition in Old Format</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a definition configured in 1.1 format.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionOpenBodyTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionOpenBodyTest.html
new file mode 100644
index 000000000..7441fb6b5
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionOpenBodyTest.html
@@ -0,0 +1,66 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition with Open BodyTest</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition with Open Body Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Insert Configured Definition with Open Body</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is a customized context</td>
+    <td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionOverrideAndNotTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionOverrideAndNotTest.html
new file mode 100644
index 000000000..1a79c50d6
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionOverrideAndNotTest.html
@@ -0,0 +1,66 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition with Overridden Content Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition with Overridden and Original Content Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Insert Configured Definition with an overridden content and one with original content</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is an overridden content</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionOverrideTemplateTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionOverrideTemplateTest.html
new file mode 100644
index 000000000..4bd54303a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionOverrideTemplateTest.html
@@ -0,0 +1,66 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition with Overridden Template Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition with Overridden Template Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Insert Configured Definition with an overridden template</td>
+	<td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the overridden template.</td>
+    <td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionOverrideTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionOverrideTest.html
new file mode 100644
index 000000000..944d451bf
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionOverrideTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition with Overridden Content Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition with Overridden Content Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Insert Configured Definition with an overridden content</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is an overridden content</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionRegexpTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionRegexpTest.html
new file mode 100644
index 000000000..88efc4e8d
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionRegexpTest.html
@@ -0,0 +1,76 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Regular Expression Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Regular Expression Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Insert Configured Definition with Regular Expression</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is layout one.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is layout two.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This definition has a message: Hello.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This definition has a message: Bye.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionReversedTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionReversedTest.html
new file mode 100644
index 000000000..659bf1021
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionReversedTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Reversed Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Reversed Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Insert Configured Definition with Reversed Attribute</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>.eltit eht si sihT</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionRoleTagTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionRoleTagTest.html
new file mode 100644
index 000000000..3fcfbdf3d
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionRoleTagTest.html
@@ -0,0 +1,66 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Role Tag Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Role Tag Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Insert Configured Definition with Specified Role in Tag</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This definition appears.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextNotPresent</td>
+	<td>This definition does not appear.</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionRoleTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionRoleTest.html
new file mode 100644
index 000000000..1a2a9b062
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionRoleTest.html
@@ -0,0 +1,66 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Role Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Role Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Insert Configured Definition with Specified Role</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This definition appears.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextNotPresent</td>
+	<td>This definition does not appear.</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionTest.html
new file mode 100644
index 000000000..598178cbe
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Insert Configured Definition</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionWildcardTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionWildcardTest.html
new file mode 100644
index 000000000..f6e1faa88
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionWildcardTest.html
@@ -0,0 +1,76 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Wildcard Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Wildcard Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Insert Configured Definition with Wildcards</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is layout one.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is layout two.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This definition has a message: Hello.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This definition has a message: Bye.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionWithConfiguredPreparerTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionWithConfiguredPreparerTest.html
new file mode 100644
index 000000000..2859c000b
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionWithConfiguredPreparerTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition with Configured Preparer Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition with Configured Preparer Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Insert Configured Definition with Preparer configured in the definition itself</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the value added by the ViewPreparer</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionWithPreparerTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionWithPreparerTest.html
new file mode 100644
index 000000000..a637a66b0
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionWithPreparerTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition with Preparer Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition with Preparer Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Insert Configured Definition with Preparer</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the value added by the ViewPreparer</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionWithUnderscoresTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionWithUnderscoresTest.html
new file mode 100644
index 000000000..87426804b
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredDefinitionWithUnderscoresTest.html
@@ -0,0 +1,52 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test underscores without localization</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>Non localized definition</td>
+	<td></td>
+</tr>
+
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredNestedDefinitionTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredNestedDefinitionTest.html
new file mode 100644
index 000000000..7bad1d0a8
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredNestedDefinitionTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Nested Definition Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Nested Definition Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Insert Nested Definition</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a nested definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredNestedListDefinitionTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredNestedListDefinitionTest.html
new file mode 100644
index 000000000..a24203bf8
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ConfiguredNestedListDefinitionTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Nested List Definition Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Nested List Definition Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Insert Nested List Definition</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a nested definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/DefinitionTagExtendTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/DefinitionTagExtendTest.html
new file mode 100644
index 000000000..1fb5964fa
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/DefinitionTagExtendTest.html
@@ -0,0 +1,60 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Definition Tag Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Definition Tag Extend Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+    <td>clickAndWait</td>
+    <td>link=Test Definition Tag extending configured and custom definitions</td>
+    <td></td>
+    </tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is an overridden title</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the header</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is an overridden content</td>
+    <td></td>
+</tr>
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/DefinitionTagListInheritTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/DefinitionTagListInheritTest.html
new file mode 100644
index 000000000..3d6f0b017
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/DefinitionTagListInheritTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Definition Tag List Inherit Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Definition Tag List Inherit Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Definition Tag with a List Inherit</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>Single attribute "stringTest" value: This is a string </td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueOne</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueTwo</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueThree</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueFour</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/DefinitionTagPreparerTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/DefinitionTagPreparerTest.html
new file mode 100644
index 000000000..21bada2ae
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/DefinitionTagPreparerTest.html
@@ -0,0 +1,62 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Definition Tag with Preparer Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Definition Tag with Preparer Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Definition Tag with Preparer</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the value added by the ViewPreparer</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/DefinitionTagTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/DefinitionTagTest.html
new file mode 100644
index 000000000..916f12659
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/DefinitionTagTest.html
@@ -0,0 +1,60 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Definition Tag Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Definition Tag Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+    <td>clickAndWait</td>
+    <td>link=Test Definition Tag</td>
+    <td></td>
+    </tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the title</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the header</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is a body</td>
+    <td></td>
+</tr>
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ImportAttributeTagAllTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ImportAttributeTagAllTest.html
new file mode 100644
index 000000000..33be7758c
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ImportAttributeTagAllTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Import Attribute Tag with no Name Specified Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Import Attribute Tag with no Name Specified Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test importAttribute Tag with no name</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>One</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>Two</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>Three </td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ImportAttributeTagInheritTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ImportAttributeTagInheritTest.html
new file mode 100644
index 000000000..dea20091e
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ImportAttributeTagInheritTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Import Attribute Tag Inherit Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Import Attribute Tag Inherit Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test importAttribute Tag with List Inherit</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>Single attribute "stringTest" value: This is a string </td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueOne</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueTwo</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueThree</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueFour</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ImportAttributeTagTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ImportAttributeTagTest.html
new file mode 100644
index 000000000..d93a563ee
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/ImportAttributeTagTest.html
@@ -0,0 +1,66 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Import Attribute Tag Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Import Attribute Tag Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test importAttribute Tag</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>Single attribute "stringTest" value: This is a string </td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueOne</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueTwo</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueThree</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/LocalizationDbTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/LocalizationDbTest.html
new file mode 100644
index 000000000..00e1d6f2a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/LocalizationDbTest.html
@@ -0,0 +1,141 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Localization Db Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Localization Db Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Localization from DB</td>
+	<td></td>
+</tr>
+<tr>
+	<td>storeText</td>
+	<td>defaultLocaleMessage</td>
+	<td>localeMessage</td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>//input[@value='Submit']</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertText</td>
+	<td>defaultLocaleMessage</td>
+	<td>${localeMessage}</td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Select another locale</td>
+	<td></td>
+</tr>
+<tr>
+	<td>select</td>
+	<td>locale</td>
+	<td>label=American English</td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>//input[@value='Submit']</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>American English locale</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Select another locale</td>
+	<td></td>
+</tr>
+<tr>
+	<td>select</td>
+	<td>locale</td>
+	<td>label=British English</td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>//input[@value='Submit']</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>British English locale</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Select another locale</td>
+	<td></td>
+</tr>
+<tr>
+	<td>select</td>
+	<td>locale</td>
+	<td>label=French</td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>//input[@value='Submit']</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>French locale</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Select another locale</td>
+	<td></td>
+</tr>
+<tr>
+	<td>select</td>
+	<td>locale</td>
+	<td>label=Italian</td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>//input[@value='Submit']</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>Italian locale</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/LocalizationTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/LocalizationTest.html
new file mode 100644
index 000000000..ca7eda136
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/LocalizationTest.html
@@ -0,0 +1,141 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put Tag Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Localization Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Localization</td>
+	<td></td>
+</tr>
+<tr>
+	<td>storeText</td>
+	<td>defaultLocaleMessage</td>
+	<td>localeMessage</td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>//input[@value='Submit']</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertText</td>
+	<td>defaultLocaleMessage</td>
+	<td>${localeMessage}</td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Select another locale</td>
+	<td></td>
+</tr>
+<tr>
+	<td>select</td>
+	<td>locale</td>
+	<td>label=American English</td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>//input[@value='Submit']</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>American English locale</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Select another locale</td>
+	<td></td>
+</tr>
+<tr>
+	<td>select</td>
+	<td>locale</td>
+	<td>label=British English</td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>//input[@value='Submit']</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>British English locale</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Select another locale</td>
+	<td></td>
+</tr>
+<tr>
+	<td>select</td>
+	<td>locale</td>
+	<td>label=French</td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>//input[@value='Submit']</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>French locale</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Select another locale</td>
+	<td></td>
+</tr>
+<tr>
+	<td>select</td>
+	<td>locale</td>
+	<td>label=Italian</td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>//input[@value='Submit']</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>Italian locale</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/PutListCascadedTagTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/PutListCascadedTagTest.html
new file mode 100644
index 000000000..a222e04b8
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/PutListCascadedTagTest.html
@@ -0,0 +1,76 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put List Cascaded Tag Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put List Cascaded Tag Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Put List Cascaded Tag</td>
+	<td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the title.</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the header</td>
+    <td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>Single attribute "stringTest" value: This is a string </td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueOne</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueTwo</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueThree</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/PutListTagInheritTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/PutListTagInheritTest.html
new file mode 100644
index 000000000..2dcd63a5f
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/PutListTagInheritTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put List Tag Inherit Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put List Tag Inherit Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Put List Tag with Inherit</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>Single attribute "stringTest" value: This is a string </td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueOne</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueTwo</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueThree</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueFour</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/PutListTagTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/PutListTagTest.html
new file mode 100644
index 000000000..b8dc0866d
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/PutListTagTest.html
@@ -0,0 +1,66 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put List Tag Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put Tag Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Put List Tag</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>Single attribute "stringTest" value: This is a string </td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueOne</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueTwo</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueThree</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/PutTagCascadedOverriddenTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/PutTagCascadedOverriddenTest.html
new file mode 100644
index 000000000..3e8816b5b
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/PutTagCascadedOverriddenTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put Tag Cascaded Overridden Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put Tag Cascaded Overridden Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Put Tag with Overridden Cascaded Attributes</td>
+	<td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the title.</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the header</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is a body</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is a configured inner definition.</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the header</td>
+    <td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/PutTagCascadedTemplateTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/PutTagCascadedTemplateTest.html
new file mode 100644
index 000000000..b629fb934
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/PutTagCascadedTemplateTest.html
@@ -0,0 +1,56 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put Tag Cascaded Template Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put Tag Cascaded Template Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Put Tag with Cascaded Attributes and Template</td>
+	<td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the title.</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the header</td>
+    <td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/PutTagCascadedTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/PutTagCascadedTest.html
new file mode 100644
index 000000000..ed6059ed6
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/PutTagCascadedTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put Tag Cascaded Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put Tag Cascaded Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Put Tag with Cascaded Attributes</td>
+	<td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the title.</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the header</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is a body</td>
+    <td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/PutTagFlushTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/PutTagFlushTest.html
new file mode 100644
index 000000000..40857c14b
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/PutTagFlushTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put Tag with Flush Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put Tag with Flush Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Put Tag with Flush</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/PutTagNestedDefinitionTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/PutTagNestedDefinitionTest.html
new file mode 100644
index 000000000..33185113d
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/PutTagNestedDefinitionTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put Tag with Nested Definition Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put Tag with Nested Definition Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Insert Nested Definition only using JSP tags</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a nested definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/PutTagNestedListDefinitionTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/PutTagNestedListDefinitionTest.html
new file mode 100644
index 000000000..2f89f8137
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/PutTagNestedListDefinitionTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put Tag with Nested List Definition Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put Tag with Nested List Definition Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Insert Nested List Definition only using JSP tags</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a nested definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/PutTagReversedTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/PutTagReversedTest.html
new file mode 100644
index 000000000..7970044f2
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/PutTagReversedTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put Tag Reversed Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put Tag Reversed Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Put Tag with Reversed Attribute</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>.eltit eht si sihT</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/PutTagTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/PutTagTest.html
new file mode 100644
index 000000000..dd4a2a484
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/PutTagTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put Tag Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put Tag Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Put Tag</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/PutTagWithELSingleEvalTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/PutTagWithELSingleEvalTest.html
new file mode 100644
index 000000000..845eee9d5
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/PutTagWithELSingleEvalTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put Tag using EL with Single Evaluation Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put Tag using EL with Single Evaluation Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Put Tag using EL to test Single Evaluation</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>${requestScope.doNotShow}</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/PutTagWithELTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/PutTagWithELTest.html
new file mode 100644
index 000000000..bad3e6e2e
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/PutTagWithELTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put Tag using EL Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put Tag Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Put Tag using EL</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>Body Content defined by and el</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/PutTagWithServletTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/PutTagWithServletTest.html
new file mode 100644
index 000000000..e5a443ff8
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/PutTagWithServletTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put Tag with Servlet as Template Test</title>
+</head>
+w<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put Tag with Servlet as Template Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Put Tag using a servlet mapping as a template</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/SetCurrentContainerTagTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/SetCurrentContainerTagTest.html
new file mode 100644
index 000000000..7624163ab
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/SetCurrentContainerTagTest.html
@@ -0,0 +1,66 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>setCurrentContainer Tag Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">setCurrentContainer Tag Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test setCurrentContainer Tag</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This definition is from an alternate container.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/TestSuite.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/TestSuite.html
new file mode 100644
index 000000000..89285f625
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/TestSuite.html
@@ -0,0 +1,641 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<body>
+
+<table>
+    <tr>
+        <td>Tiles 2 Tests</td>
+    </tr>
+    <tr>
+        <td><a href="WelcomePageTest.html">Welcome Page Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="ConfiguredDefinitionTest.html">Configured Definition Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="ConfiguredDefinitionExprTest.html">Configured Definition With Expression Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="ConfiguredDefinitionIgnoreTest.html">Configured Definition with Ignore Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="ConfiguredDefinitionFlushTest.html">Configured Definition with Flush Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="ConfiguredDefinitionFreeMarkerTest.html">Configured Definition with FreeMarker Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="ConfiguredDefinitionWithPreparerTest.html">Configured Definition with Preparer Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="ConfiguredDefinitionWithConfiguredPreparerTest.html">Configured Definition with Configured Preparer Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="ConfiguredDefinitionFromClasspathTest.html">Configured Definition from Classpath Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="ConfiguredDefinitionOverrideTest.html">Configured Definition with Overridden Content Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="ConfiguredDefinitionOverrideTemplateTest.html">Configured Definition with Overridden Template Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="ConfiguredDefinitionOverrideAndNotTest.html">Configured Definition with Overridden and Original Content Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="ConfiguredDefinitionInlineTest.html">Configured Definition with Inline Content Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="ConfiguredCompositeDefinitionTest.html">Configured Composite Definition Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="ConfiguredDefinitionExceptionTest.html">Configured Definition with Exception Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="ConfiguredDefinitionOldFormatTest.html">Configured Definition Old Format Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="ConfiguredDefinitionCascadedTest.html">Configured Definition Cascaded Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="ConfiguredDefinitionCascadedOverriddenTest.html">Configured Definition Cascaded Overridden Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="ConfiguredDefinitionCascadedTemplateTest.html">Configured Definition Cascaded Template Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="ConfiguredDefinitionCascadedListTest.html">Configured Definition Cascaded List Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="ConfiguredDefinitionReversedTest.html">Configured Definition Reversed Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="ConfiguredDefinitionAttributePreparerTest.html">Configured Definition Attribute Preparer Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="ConfiguredNestedDefinitionTest.html">Configured Nested Definition Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="ConfiguredNestedListDefinitionTest.html">Configured Nested List Definition Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="ConfiguredDefinitionELTest.html">Configured Definition EL Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="ConfiguredDefinitionMVELTest.html">Configured Definition MVEL Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="ConfiguredDefinitionOGNLTest.html">Configured Definition OGNL Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="ConfiguredDefinitionELSingleEvalTest.html">Configured Definition EL with Single Evaluation Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="ConfiguredDefinitionOpenBodyTest.html">Configured Definition with Open Body Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="ConfiguredDefinitionDefaultValuesTest.html">Configured Definition with Default Values Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="ConfiguredDefinitionWildcardTest.html">Configured Definition Wildcard Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="ConfiguredDefinitionRegexpTest.html">Configured Definition Regular Expression Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="ConfiguredDefinitionWithUnderscoresTest.html">Configured Definition With Underscores Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="PutTagTest.html">Put Tag Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="PutTagFlushTest.html">Put Tag with Flush Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="PutTagWithELTest.html">Put Tag using EL Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="PutTagWithELSingleEvalTest.html">Put Tag using EL with Single Evaluation Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="PutTagWithServletTest.html">Put Tag with Servlet as Template Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="PutTagCascadedTest.html">Put Tag Cascaded Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="PutTagCascadedOverriddenTest.html">Put Tag Cascaded Overridden Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="PutTagCascadedTemplateTest.html">Put Tag Cascaded Template Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="PutTagReversedTest.html">Put Tag Reversed Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="PutTagNestedDefinitionTest.html">Put Tag with Nested Definition Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="PutTagNestedListDefinitionTest.html">Put Tag with Nested List Definition Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="PutListTagTest.html">Put List Tag Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="PutListCascadedTagTest.html">Put List Cascaded Tag Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="PutListTagInheritTest.html">Put List Tag Inherit Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="LocalizationTest.html">Localization Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="ImportAttributeTagTest.html">Import Attribute Tag Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="ImportAttributeTagAllTest.html">Import Attribute Tag with no Name Specified Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="ImportAttributeTagInheritTest.html">Import Attribute Tag Inherit Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="TilesDefinitionFilterTest.html">Tiles Definition Filter Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="TilesDispatchServletTest.html">Tiles Dispatch Servlet Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="SetCurrentContainerTagTest.html">setCurrentContainer Tag Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="DefinitionTagTest.html">Definition Tag Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="DefinitionTagExtendTest.html">Definition Tag Extend Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="DefinitionTagListInheritTest.html">Definition Tag List Inherit Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="DefinitionTagPreparerTest.html">Definition Tag with Preparer Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="CompositeDefinitionWithInnerConfiguredDefinitionTest.html">Composite Definition with inner Configured Definition Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="CompositeDefinitionWithInnerDefinitionTest.html">Composite Definition with inner Definition Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="CompositeDefinitionWithInnerConfiguredDefinitionNoTypeTest.html">Composite Definition with inner Configured Definition with no Type Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="CompositeDefinitionWithInnerDefinitionNoTypeTest.html">Composite Definition with inner Definition with no Type Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="ConfiguredDefinitionRoleTest.html">Configured Definition Role Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="ConfiguredDefinitionRoleTagTest.html">Configured Definition Role Tag Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="ConfiguredDefinitionAttributeRolesTest.html">Configured Definition Attribute Roles Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="ConfiguredDefinitionAttributeRolesTagsTest.html">Configured Definition Attribute Roles Tags Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="ConfiguredDefinitionDbTest.html">Configured Definition Db Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="ConfiguredDefinitionExtendedDbTest.html">Configured Definition Extended Db Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="LocalizationDbTest.html">Localization Db Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/WelcomePageTest.html">FreeMarker: Welcome Page Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/ConfiguredDefinitionTest.html">FreeMarker: Configured Definition Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/ConfiguredDefinitionIgnoreTest.html">FreeMarker: Configured Definition with Ignore Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/ConfiguredDefinitionFlushTest.html">FreeMarker: Configured Definition with Flush Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/ConfiguredDefinitionWithPreparerTest.html">FreeMarker: Configured Definition with Preparer Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/ConfiguredDefinitionWithConfiguredPreparerTest.html">FreeMarker: Configured Definition with Configured Preparer Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/ConfiguredDefinitionFromClasspathTest.html">FreeMarker: Configured Definition from Classpath Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/ConfiguredDefinitionOverrideTest.html">FreeMarker: Configured Definition with Overridden Content Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/ConfiguredDefinitionOverrideTemplateTest.html">FreeMarker: Configured Definition with Overridden Template Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/ConfiguredDefinitionOverrideAndNotTest.html">FreeMarker: Configured Definition with Overridden and Original Content Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/ConfiguredDefinitionInlineTest.html">FreeMarker: Configured Definition with Inline Content Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/ConfiguredCompositeDefinitionTest.html">FreeMarker: Configured Composite Definition Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/ConfiguredDefinitionExceptionTest.html">FreeMarker: Configured Definition with Exception Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/ConfiguredDefinitionOldFormatTest.html">FreeMarker: Configured Definition Old Format Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/ConfiguredDefinitionCascadedTest.html">FreeMarker: Configured Definition Cascaded Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/ConfiguredDefinitionCascadedOverriddenTest.html">FreeMarker: Configured Definition Cascaded Overridden Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/ConfiguredDefinitionCascadedTemplateTest.html">FreeMarker: Configured Definition Cascaded Template Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/ConfiguredDefinitionCascadedListTest.html">FreeMarker: Configured Definition Cascaded List Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/ConfiguredDefinitionReversedTest.html">FreeMarker: Configured Definition Reversed Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/ConfiguredDefinitionAttributePreparerTest.html">FreeMarker: Configured Definition Attribute Preparer Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/ConfiguredNestedDefinitionTest.html">FreeMarker: Configured Nested Definition Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/ConfiguredNestedListDefinitionTest.html">FreeMarker: Configured Nested List Definition Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/ConfiguredDefinitionELTest.html">FreeMarker: Configured Definition EL Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/ConfiguredDefinitionMVELTest.html">FreeMarker: Configured Definition MVEL Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/ConfiguredDefinitionOGNLTest.html">FreeMarker: Configured Definition OGNL Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/ConfiguredDefinitionELSingleEvalTest.html">FreeMarker: Configured Definition EL with Single Evaluation Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/ConfiguredDefinitionOpenBodyTest.html">FreeMarker: Configured Definition with Open Body Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/ConfiguredDefinitionDefaultValuesTest.html">FreeMarker: Configured Definition with Default Values Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/ConfiguredDefinitionWildcardTest.html">FreeMarker: Configured Definition Wildcard Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/ConfiguredDefinitionRegexpTest.html">FreeMarker: Configured Definition Regular Expression Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/ConfiguredDefinitionWithUnderscoresTest.html">FreeMarker: Configured Definition With Underscores Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/PutTagTest.html">FreeMarker: Put Tag Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/PutTagFlushTest.html">FreeMarker: Put Tag with Flush Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/PutTagWithELTest.html">FreeMarker: Put Tag using EL Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/PutTagWithELSingleEvalTest.html">FreeMarker: Put Tag using EL with Single Evaluation Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/PutTagWithServletTest.html">FreeMarker: Put Tag with Servlet as Template Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/PutTagCascadedTest.html">FreeMarker: Put Tag Cascaded Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/PutTagCascadedOverriddenTest.html">FreeMarker: Put Tag Cascaded Overridden Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/PutTagCascadedTemplateTest.html">FreeMarker: Put Tag Cascaded Template Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/PutTagReversedTest.html">FreeMarker: Put Tag Reversed Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/PutTagNestedDefinitionTest.html">FreeMarker: Put Tag with Nested Definition Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/PutTagNestedListDefinitionTest.html">FreeMarker: Put Tag with Nested List Definition Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/PutListTagTest.html">FreeMarker: Put List Tag Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/PutListCascadedTagTest.html">FreeMarker: Put List Cascaded Tag Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/PutListTagInheritTest.html">FreeMarker: Put List Tag Inherit Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/LocalizationTest.html">FreeMarker: Localization Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/ImportAttributeTagTest.html">FreeMarker: Import Attribute Tag Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/ImportAttributeTagAllTest.html">FreeMarker: Import Attribute Tag with no Name Specified Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/ImportAttributeTagInheritTest.html">FreeMarker: Import Attribute Tag Inherit Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/TilesDefinitionFilterTest.html">FreeMarker: Tiles Definition Filter Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/TilesDispatchServletTest.html">FreeMarker: Tiles Dispatch Servlet Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/SetCurrentContainerTagTest.html">FreeMarker: setCurrentContainer Tag Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/DefinitionTagTest.html">FreeMarker: Definition Tag Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/DefinitionTagExtendTest.html">FreeMarker: Definition Tag Extend Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/DefinitionTagListInheritTest.html">FreeMarker: Definition Tag List Inherit Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/DefinitionTagPreparerTest.html">FreeMarker: Definition Tag with Preparer Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/CompositeDefinitionWithInnerConfiguredDefinitionTest.html">FreeMarker: Composite Definition with inner Configured Definition Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/CompositeDefinitionWithInnerDefinitionTest.html">FreeMarker: Composite Definition with inner Definition Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/CompositeDefinitionWithInnerConfiguredDefinitionNoTypeTest.html">FreeMarker: Composite Definition with inner Configured Definition with no Type Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/CompositeDefinitionWithInnerDefinitionNoTypeTest.html">FreeMarker: Composite Definition with inner Definition with no Type Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/ConfiguredDefinitionRoleTest.html">FreeMarker: Configured Definition Role Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/ConfiguredDefinitionRoleTagTest.html">FreeMarker: Configured Definition Role Tag Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/ConfiguredDefinitionAttributeRolesTest.html">FreeMarker: Configured Definition Attribute Roles Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/ConfiguredDefinitionAttributeRolesTagsTest.html">FreeMarker: Configured Definition Attribute Roles Tags Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/ConfiguredDefinitionDbTest.html">FreeMarker: Configured Definition Db Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/ConfiguredDefinitionExtendedDbTest.html">FreeMarker: Configured Definition Extended Db Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="freemarker/ConfiguredDefinitionInModuleTest.html">FreeMarker: Configured Definition in Module Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/WelcomePageTest.html">Velocity: Welcome Page Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/ConfiguredDefinitionTest.html">Velocity: Configured Definition Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/ConfiguredDefinitionIgnoreTest.html">Velocity: Configured Definition with Ignore Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/ConfiguredDefinitionFlushTest.html">Velocity: Configured Definition with Flush Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/ConfiguredDefinitionWithPreparerTest.html">Velocity: Configured Definition with Preparer Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/ConfiguredDefinitionWithConfiguredPreparerTest.html">Velocity: Configured Definition with Configured Preparer Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/ConfiguredDefinitionFromClasspathTest.html">Velocity: Configured Definition from Classpath Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/ConfiguredDefinitionOverrideTest.html">Velocity: Configured Definition with Overridden Content Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/ConfiguredDefinitionOverrideTemplateTest.html">Velocity: Configured Definition with Overridden Template Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/ConfiguredDefinitionOverrideAndNotTest.html">Velocity: Configured Definition with Overridden and Original Content Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/ConfiguredDefinitionInlineTest.html">Velocity: Configured Definition with Inline Content Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/ConfiguredCompositeDefinitionTest.html">Velocity: Configured Composite Definition Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/ConfiguredDefinitionExceptionTest.html">Velocity: Configured Definition with Exception Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/ConfiguredDefinitionOldFormatTest.html">Velocity: Configured Definition Old Format Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/ConfiguredDefinitionCascadedTest.html">Velocity: Configured Definition Cascaded Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/ConfiguredDefinitionCascadedOverriddenTest.html">Velocity: Configured Definition Cascaded Overridden Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/ConfiguredDefinitionCascadedTemplateTest.html">Velocity: Configured Definition Cascaded Template Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/ConfiguredDefinitionCascadedListTest.html">Velocity: Configured Definition Cascaded List Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/ConfiguredDefinitionReversedTest.html">Velocity: Configured Definition Reversed Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/ConfiguredDefinitionAttributePreparerTest.html">Velocity: Configured Definition Attribute Preparer Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/ConfiguredNestedDefinitionTest.html">Velocity: Configured Nested Definition Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/ConfiguredNestedListDefinitionTest.html">Velocity: Configured Nested List Definition Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/ConfiguredDefinitionELTest.html">Velocity: Configured Definition EL Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/ConfiguredDefinitionMVELTest.html">Velocity: Configured Definition MVEL Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/ConfiguredDefinitionOGNLTest.html">Velocity: Configured Definition OGNL Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/ConfiguredDefinitionELSingleEvalTest.html">Velocity: Configured Definition EL with Single Evaluation Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/ConfiguredDefinitionOpenBodyTest.html">Velocity: Configured Definition with Open Body Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/ConfiguredDefinitionDefaultValuesTest.html">Velocity: Configured Definition with Default Values Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/ConfiguredDefinitionWildcardTest.html">Velocity: Configured Definition Wildcard Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/ConfiguredDefinitionRegexpTest.html">Velocity: Configured Definition Regular Expression Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/ConfiguredDefinitionWithUnderscoresTest.html">Velocity: Configured Definition With Underscores Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/PutTagTest.html">Velocity: Put Tag Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/PutTagFlushTest.html">Velocity: Put Tag with Flush Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/PutTagWithELTest.html">Velocity: Put Tag using EL Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/PutTagWithELSingleEvalTest.html">Velocity: Put Tag using EL with Single Evaluation Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/PutTagWithServletTest.html">Velocity: Put Tag with Servlet as Template Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/PutTagCascadedTest.html">Velocity: Put Tag Cascaded Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/PutTagCascadedOverriddenTest.html">Velocity: Put Tag Cascaded Overridden Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/PutTagCascadedTemplateTest.html">Velocity: Put Tag Cascaded Template Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/PutTagReversedTest.html">Velocity: Put Tag Reversed Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/PutTagNestedDefinitionTest.html">Velocity: Put Tag with Nested Definition Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/PutTagNestedListDefinitionTest.html">Velocity: Put Tag with Nested List Definition Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/PutListTagTest.html">Velocity: Put List Tag Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/PutListCascadedTagTest.html">Velocity: Put List Cascaded Tag Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/PutListTagInheritTest.html">Velocity: Put List Tag Inherit Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/LocalizationTest.html">Velocity: Localization Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/ImportAttributeTagTest.html">Velocity: Import Attribute Tag Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/ImportAttributeTagAllTest.html">Velocity: Import Attribute Tag with no Name Specified Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/ImportAttributeTagInheritTest.html">Velocity: Import Attribute Tag Inherit Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/TilesDefinitionFilterTest.html">Velocity: Tiles Definition Filter Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/TilesDispatchServletTest.html">Velocity: Tiles Dispatch Servlet Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/SetCurrentContainerTagTest.html">Velocity: setCurrentContainer Tag Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/DefinitionTagTest.html">Velocity: Definition Tag Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/DefinitionTagExtendTest.html">Velocity: Definition Tag Extend Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/DefinitionTagListInheritTest.html">Velocity: Definition Tag List Inherit Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/DefinitionTagPreparerTest.html">Velocity: Definition Tag with Preparer Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/CompositeDefinitionWithInnerConfiguredDefinitionTest.html">Velocity: Composite Definition with inner Configured Definition Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/CompositeDefinitionWithInnerDefinitionTest.html">Velocity: Composite Definition with inner Definition Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/CompositeDefinitionWithInnerConfiguredDefinitionNoTypeTest.html">Velocity: Composite Definition with inner Configured Definition with no Type Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/CompositeDefinitionWithInnerDefinitionNoTypeTest.html">Velocity: Composite Definition with inner Definition with no Type Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/ConfiguredDefinitionRoleTest.html">Velocity: Configured Definition Role Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/ConfiguredDefinitionRoleTagTest.html">Velocity: Configured Definition Role Tag Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/ConfiguredDefinitionAttributeRolesTest.html">Velocity: Configured Definition Attribute Roles Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/ConfiguredDefinitionAttributeRolesTagsTest.html">Velocity: Configured Definition Attribute Roles Tags Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/ConfiguredDefinitionDbTest.html">Velocity: Configured Definition Db Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/ConfiguredDefinitionExtendedDbTest.html">Velocity: Configured Definition Extended Db Test</a></td>
+    </tr>
+    <tr>
+        <td><a href="velocity/ConfiguredDefinitionInModuleTest.html">Velocity: Configured Definition in Module Test</a></td>
+    </tr>
+</table>
+</body>
+</html>
\ No newline at end of file
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/TilesDefinitionFilterTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/TilesDefinitionFilterTest.html
new file mode 100644
index 000000000..315082699
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/TilesDefinitionFilterTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Tiles Definition Filter Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put Tag Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Tiles Definition Filter</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This Content should be wrapped with the standard layout.</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/TilesDispatchServletTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/TilesDispatchServletTest.html
new file mode 100644
index 000000000..b30ecfd58
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/TilesDispatchServletTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Tiles Dispatch Servlet Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put Tag Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Test Tiles Dispatch Servlet</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/WelcomePageTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/WelcomePageTest.html
new file mode 100644
index 000000000..3c257bd38
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/WelcomePageTest.html
@@ -0,0 +1,50 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Registration Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Welcome Page Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTitle</td>
+	<td>Tiles 2 Test Application</td>
+	<td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>Tiles 2 Test Application</td>
+    <td></td>
+</tr>
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/CompositeDefinitionWithInnerConfiguredDefinitionNoTypeTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/CompositeDefinitionWithInnerConfiguredDefinitionNoTypeTest.html
new file mode 100644
index 000000000..544560d8f
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/CompositeDefinitionWithInnerConfiguredDefinitionNoTypeTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Composite Definition with Inner Configured Definition with no Type Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Composite Definition with Inner Configured Definition with no Type Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Insert Definition that contains another definition inside (configured via tiles-defs.xml) using JSP tags without types</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a composite definition with tags.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a configured inner definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/CompositeDefinitionWithInnerConfiguredDefinitionTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/CompositeDefinitionWithInnerConfiguredDefinitionTest.html
new file mode 100644
index 000000000..8c8c2d150
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/CompositeDefinitionWithInnerConfiguredDefinitionTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Composite Definition with Inner Configured Definition Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Composite Definition with Inner Configured Definition Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Insert Definition that contains another definition inside (configured via tiles-defs.xml) using JSP tags</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a composite definition with tags.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a configured inner definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/CompositeDefinitionWithInnerDefinitionNoTypeTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/CompositeDefinitionWithInnerDefinitionNoTypeTest.html
new file mode 100644
index 000000000..9d2991c96
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/CompositeDefinitionWithInnerDefinitionNoTypeTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Composite Definition with Inner Configured Definition with no Type Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Composite Definition with Inner Configured Definition with no Type Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Insert Definition that contains another definition inside using JSP tags without types</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a composite definition with tags.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is an inner definition with tags.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/CompositeDefinitionWithInnerDefinitionTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/CompositeDefinitionWithInnerDefinitionTest.html
new file mode 100644
index 000000000..8658b5b58
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/CompositeDefinitionWithInnerDefinitionTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Composite Definition with Inner Definition Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Composite Definition with Inner Definition Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Insert Definition that contains another definition inside using JSP tags</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a composite definition with tags.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is an inner definition with tags.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredCompositeDefinitionTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredCompositeDefinitionTest.html
new file mode 100644
index 000000000..0a6f2f6d1
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredCompositeDefinitionTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Composite Definition Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+w<tr><td rowspan="1" colspan="3">Configured Composite Definition Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Insert Configured Definition that contains another definition inside</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a configured composite definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a configured inner definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionAttributePreparerTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionAttributePreparerTest.html
new file mode 100644
index 000000000..c3091a008
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionAttributePreparerTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Attribute Preparer Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Attribute Preparer Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Insert Configured Definition with Attribute Preparer</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the value added by the AttributeViewPreparer</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionAttributeRolesTagsTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionAttributeRolesTagsTest.html
new file mode 100644
index 000000000..2df9c59db
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionAttributeRolesTagsTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Attribute Roles Tags Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Attribute Roles Tags Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Insert Configured Definition with Attribute that have Roles in Tags</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextNotPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionAttributeRolesTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionAttributeRolesTest.html
new file mode 100644
index 000000000..51b0478d7
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionAttributeRolesTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Attribute Roles Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Attribute Roles Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Insert Configured Definition with Attribute that have Roles</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextNotPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionCascadedListTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionCascadedListTest.html
new file mode 100644
index 000000000..3e5f3cd3e
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionCascadedListTest.html
@@ -0,0 +1,76 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Cascaded List Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Cascaded List Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Insert Configured Cascaded Definition with List</td>
+	<td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the title.</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the header</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>Single attribute "stringTest" value: This is a string </td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>valueOne</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>valueTwo</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>valueThree</td>
+    <td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionCascadedOverriddenTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionCascadedOverriddenTest.html
new file mode 100644
index 000000000..1ff01cbdb
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionCascadedOverriddenTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Cascaded Overridden Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Cascaded Overridden Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Insert Configured Cascaded Definition with Override</td>
+	<td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the title.</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the header</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is a body</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is a configured inner definition.</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the header</td>
+    <td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionCascadedTemplateTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionCascadedTemplateTest.html
new file mode 100644
index 000000000..2cc9e7534
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionCascadedTemplateTest.html
@@ -0,0 +1,56 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Cascaded Template Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Cascaded Template Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Insert Configured Cascaded Definition with Template</td>
+	<td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the title.</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the header</td>
+    <td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionCascadedTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionCascadedTest.html
new file mode 100644
index 000000000..daaa243eb
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionCascadedTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Cascaded Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Cascaded Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Insert Configured Cascaded Definition</td>
+	<td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the title.</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the header</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is a body</td>
+    <td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionDbTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionDbTest.html
new file mode 100644
index 000000000..0f299eb94
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionDbTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Db Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Db Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Insert Configured Definition from DB</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionDefaultValuesTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionDefaultValuesTest.html
new file mode 100644
index 000000000..5797df38a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionDefaultValuesTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition with Default Values Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition with Default Values Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Insert Configured Definition with Default Values</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the alternate header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the default body in the tag.</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionELSingleEvalTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionELSingleEvalTest.html
new file mode 100644
index 000000000..b0c80f68d
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionELSingleEvalTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition EL with Single Evaluation Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition EL with Single Evaluation Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Insert Configured Definition with EL to test Single Evaluation</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a configured definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>${requestScope.doNotShow}</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionELTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionELTest.html
new file mode 100644
index 000000000..90510d2b6
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionELTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition EL Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition EL Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Insert Configured Definition with EL</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a configured composite definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a configured inner definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionExceptionTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionExceptionTest.html
new file mode 100644
index 000000000..2ba0e4341
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionExceptionTest.html
@@ -0,0 +1,51 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition with Exception Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Insert Configured Definition with an exception in an attribute page</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextNotPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionExtendedDbTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionExtendedDbTest.html
new file mode 100644
index 000000000..aa5ce9ba2
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionExtendedDbTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Extended Db Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Extended Db Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Insert Extended Configured Definition from DB</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is an extended definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionFlushTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionFlushTest.html
new file mode 100644
index 000000000..6f611bcde
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionFlushTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition with Flush Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition with Flush Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Insert Configured Definition with Flush</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionFromClasspathTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionFromClasspathTest.html
new file mode 100644
index 000000000..f86f6d968
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionFromClasspathTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition from Classpath Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition from Classpath Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Insert Configured Classpath Definition</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This tile was loaded from the classpath</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionIgnoreTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionIgnoreTest.html
new file mode 100644
index 000000000..35e3c6d57
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionIgnoreTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Ignore Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Ignore Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Insert Configured Definition with Ignore</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextNotPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionInModuleTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionInModuleTest.html
new file mode 100644
index 000000000..91079a49a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionInModuleTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition in Module Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition in Module Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Insert Configured Definition in Module</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This definition is from an alternate container.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This body is loaded from the "alt" module.</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionInlineTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionInlineTest.html
new file mode 100644
index 000000000..13b8ad488
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionInlineTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition with Inline Content Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition with Inline Content Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Insert Configured Definition with an inline content</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is an inline content</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionMVELTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionMVELTest.html
new file mode 100644
index 000000000..892876678
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionMVELTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition MVEL Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition MVEL Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Insert Configured Definition with MVEL</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a configured composite definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a configured inner definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionOGNLTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionOGNLTest.html
new file mode 100644
index 000000000..809a80998
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionOGNLTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition OGNL Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition OGNL Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Insert Configured Definition with OGNL</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a configured composite definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a configured inner definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionOldFormatTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionOldFormatTest.html
new file mode 100644
index 000000000..c285f7599
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionOldFormatTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Old Format Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Old Format Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Insert Configured Definition in Old Format</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a definition configured in 1.1 format.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionOpenBodyTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionOpenBodyTest.html
new file mode 100644
index 000000000..d2ae633fb
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionOpenBodyTest.html
@@ -0,0 +1,66 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition with Open BodyTest</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition with Open Body Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Insert Configured Definition with Open Body</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is a customized context</td>
+    <td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionOverrideAndNotTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionOverrideAndNotTest.html
new file mode 100644
index 000000000..cc33488cf
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionOverrideAndNotTest.html
@@ -0,0 +1,66 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition with Overridden Content Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition with Overridden and Original Content Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Insert Configured Definition with an overridden content and one with original content</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is an overridden content</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionOverrideTemplateTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionOverrideTemplateTest.html
new file mode 100644
index 000000000..ae3e0454c
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionOverrideTemplateTest.html
@@ -0,0 +1,66 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition with Overridden Template Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition with Overridden Template Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Insert Configured Definition with an overridden template</td>
+	<td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the overridden template.</td>
+    <td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionOverrideTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionOverrideTest.html
new file mode 100644
index 000000000..1894c7477
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionOverrideTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition with Overridden Content Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition with Overridden Content Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Insert Configured Definition with an overridden content</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is an overridden content</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionRegexpTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionRegexpTest.html
new file mode 100644
index 000000000..42757b590
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionRegexpTest.html
@@ -0,0 +1,76 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Regular Expression Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Regular Expression Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Insert Configured Definition with Regular Expression</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is layout one.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is layout two.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This definition has a message: Hello.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This definition has a message: Bye.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionReversedTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionReversedTest.html
new file mode 100644
index 000000000..e3783f56f
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionReversedTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Reversed Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Reversed Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Insert Configured Definition with Reversed Attribute</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>.eltit eht si sihT</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionRoleTagTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionRoleTagTest.html
new file mode 100644
index 000000000..1eca4c9e1
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionRoleTagTest.html
@@ -0,0 +1,66 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Role Tag Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Role Tag Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Insert Configured Definition with Specified Role in Tag</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This definition appears.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextNotPresent</td>
+	<td>This definition does not appear.</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionRoleTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionRoleTest.html
new file mode 100644
index 000000000..0dc25d69f
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionRoleTest.html
@@ -0,0 +1,66 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Role Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Role Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Insert Configured Definition with Specified Role</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This definition appears.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextNotPresent</td>
+	<td>This definition does not appear.</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionTest.html
new file mode 100644
index 000000000..ff46f2980
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Insert Configured Definition</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionWildcardTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionWildcardTest.html
new file mode 100644
index 000000000..a44871bfd
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionWildcardTest.html
@@ -0,0 +1,76 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Wildcard Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Wildcard Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Insert Configured Definition with Wildcards</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is layout one.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is layout two.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This definition has a message: Hello.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This definition has a message: Bye.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionWithConfiguredPreparerTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionWithConfiguredPreparerTest.html
new file mode 100644
index 000000000..11aa6acf5
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionWithConfiguredPreparerTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition with Configured Preparer Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition with Configured Preparer Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Insert Configured Definition with Preparer configured in the definition itself</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the value added by the ViewPreparer</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionWithPreparerTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionWithPreparerTest.html
new file mode 100644
index 000000000..fcac65345
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionWithPreparerTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition with Preparer Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition with Preparer Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Insert Configured Definition with Preparer</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the value added by the ViewPreparer</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionWithUnderscoresTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionWithUnderscoresTest.html
new file mode 100644
index 000000000..074a4bf15
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredDefinitionWithUnderscoresTest.html
@@ -0,0 +1,52 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test underscores without localization</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>Non localized definition</td>
+	<td></td>
+</tr>
+
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredNestedDefinitionTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredNestedDefinitionTest.html
new file mode 100644
index 000000000..cef86a151
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredNestedDefinitionTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Nested Definition Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Nested Definition Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Insert Nested Definition</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a nested definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredNestedListDefinitionTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredNestedListDefinitionTest.html
new file mode 100644
index 000000000..2939c3160
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ConfiguredNestedListDefinitionTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Nested List Definition Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Nested List Definition Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Insert Nested List Definition</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a nested definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/DefinitionTagExtendTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/DefinitionTagExtendTest.html
new file mode 100644
index 000000000..7cf6456e6
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/DefinitionTagExtendTest.html
@@ -0,0 +1,60 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Definition Tag Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Definition Tag Extend Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+    <td>clickAndWait</td>
+    <td>link=FreeMarker: Test Definition Tag extending configured and custom definitions</td>
+    <td></td>
+    </tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is an overridden title</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the header</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is an overridden content</td>
+    <td></td>
+</tr>
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/DefinitionTagListInheritTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/DefinitionTagListInheritTest.html
new file mode 100644
index 000000000..aac2a3f7f
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/DefinitionTagListInheritTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Definition Tag List Inherit Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Definition Tag List Inherit Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Definition Tag with a List Inherit</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>Single attribute "stringTest" value: This is a string </td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueOne</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueTwo</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueThree</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueFour</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/DefinitionTagPreparerTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/DefinitionTagPreparerTest.html
new file mode 100644
index 000000000..41b994ec4
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/DefinitionTagPreparerTest.html
@@ -0,0 +1,62 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Definition Tag with Preparer Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Definition Tag with Preparer Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Definition Tag with Preparer</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the value added by the ViewPreparer</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/DefinitionTagTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/DefinitionTagTest.html
new file mode 100644
index 000000000..ebf27cdea
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/DefinitionTagTest.html
@@ -0,0 +1,60 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Definition Tag Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Definition Tag Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+    <td>clickAndWait</td>
+    <td>link=FreeMarker: Test Definition Tag</td>
+    <td></td>
+    </tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the title</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the header</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is a body</td>
+    <td></td>
+</tr>
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ImportAttributeTagAllTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ImportAttributeTagAllTest.html
new file mode 100644
index 000000000..6d7f73651
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ImportAttributeTagAllTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Import Attribute Tag with no Name Specified Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Import Attribute Tag with no Name Specified Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test importAttribute Tag with no name</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>One</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>Two</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>Three </td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ImportAttributeTagInheritTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ImportAttributeTagInheritTest.html
new file mode 100644
index 000000000..3735b8419
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ImportAttributeTagInheritTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Import Attribute Tag Inherit Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Import Attribute Tag Inherit Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test importAttribute Tag with List Inherit</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>Single attribute "stringTest" value: This is a string </td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueOne</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueTwo</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueThree</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueFour</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ImportAttributeTagTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ImportAttributeTagTest.html
new file mode 100644
index 000000000..817df6ae5
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/ImportAttributeTagTest.html
@@ -0,0 +1,66 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Import Attribute Tag Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Import Attribute Tag Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test importAttribute Tag</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>Single attribute "stringTest" value: This is a string </td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueOne</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueTwo</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueThree</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/LocalizationTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/LocalizationTest.html
new file mode 100644
index 000000000..558b7553c
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/LocalizationTest.html
@@ -0,0 +1,141 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put Tag Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Localization Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Localization</td>
+	<td></td>
+</tr>
+<tr>
+	<td>storeText</td>
+	<td>defaultLocaleMessage</td>
+	<td>localeMessage</td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>//input[@value='Submit']</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertText</td>
+	<td>defaultLocaleMessage</td>
+	<td>${localeMessage}</td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Select another locale</td>
+	<td></td>
+</tr>
+<tr>
+	<td>select</td>
+	<td>locale</td>
+	<td>label=American English</td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>//input[@value='Submit']</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>American English locale</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Select another locale</td>
+	<td></td>
+</tr>
+<tr>
+	<td>select</td>
+	<td>locale</td>
+	<td>label=British English</td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>//input[@value='Submit']</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>British English locale</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Select another locale</td>
+	<td></td>
+</tr>
+<tr>
+	<td>select</td>
+	<td>locale</td>
+	<td>label=French</td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>//input[@value='Submit']</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>French locale</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Select another locale</td>
+	<td></td>
+</tr>
+<tr>
+	<td>select</td>
+	<td>locale</td>
+	<td>label=Italian</td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>//input[@value='Submit']</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>Italian locale</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/PutListCascadedTagTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/PutListCascadedTagTest.html
new file mode 100644
index 000000000..35bb4df3a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/PutListCascadedTagTest.html
@@ -0,0 +1,76 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put List Cascaded Tag Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put List Cascaded Tag Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Put List Cascaded Tag</td>
+	<td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the title.</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the header</td>
+    <td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>Single attribute "stringTest" value: This is a string </td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueOne</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueTwo</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueThree</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/PutListTagInheritTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/PutListTagInheritTest.html
new file mode 100644
index 000000000..59d5444ee
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/PutListTagInheritTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put List Tag Inherit Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put List Tag Inherit Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Put List Tag with Inherit</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>Single attribute "stringTest" value: This is a string </td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueOne</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueTwo</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueThree</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueFour</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/PutListTagTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/PutListTagTest.html
new file mode 100644
index 000000000..696717c32
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/PutListTagTest.html
@@ -0,0 +1,66 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put List Tag Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put Tag Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Put List Tag</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>Single attribute "stringTest" value: This is a string </td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueOne</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueTwo</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueThree</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/PutTagCascadedOverriddenTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/PutTagCascadedOverriddenTest.html
new file mode 100644
index 000000000..f897957db
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/PutTagCascadedOverriddenTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put Tag Cascaded Overridden Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put Tag Cascaded Overridden Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Put Tag with Overridden Cascaded Attributes</td>
+	<td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the title.</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the header</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is a body</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is a configured inner definition.</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the header</td>
+    <td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/PutTagCascadedTemplateTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/PutTagCascadedTemplateTest.html
new file mode 100644
index 000000000..f176b9c59
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/PutTagCascadedTemplateTest.html
@@ -0,0 +1,56 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put Tag Cascaded Template Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put Tag Cascaded Template Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Put Tag with Cascaded Attributes and Template</td>
+	<td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the title.</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the header</td>
+    <td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/PutTagCascadedTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/PutTagCascadedTest.html
new file mode 100644
index 000000000..cfbc75843
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/PutTagCascadedTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put Tag Cascaded Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put Tag Cascaded Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Put Tag with Cascaded Attributes</td>
+	<td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the title.</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the header</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is a body</td>
+    <td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/PutTagFlushTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/PutTagFlushTest.html
new file mode 100644
index 000000000..326b407b5
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/PutTagFlushTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put Tag with Flush Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put Tag with Flush Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Put Tag with Flush</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/PutTagNestedDefinitionTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/PutTagNestedDefinitionTest.html
new file mode 100644
index 000000000..50880ad5b
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/PutTagNestedDefinitionTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put Tag with Nested Definition Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put Tag with Nested Definition Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Insert Nested Definition only using JSP tags</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a nested definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/PutTagNestedListDefinitionTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/PutTagNestedListDefinitionTest.html
new file mode 100644
index 000000000..41a73d603
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/PutTagNestedListDefinitionTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put Tag with Nested List Definition Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put Tag with Nested List Definition Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Insert Nested List Definition only using JSP tags</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a nested definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/PutTagReversedTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/PutTagReversedTest.html
new file mode 100644
index 000000000..028152713
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/PutTagReversedTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put Tag Reversed Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put Tag Reversed Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Put Tag with Reversed Attribute</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>.eltit eht si sihT</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/PutTagTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/PutTagTest.html
new file mode 100644
index 000000000..64804f082
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/PutTagTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put Tag Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put Tag Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Put Tag</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/PutTagWithELSingleEvalTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/PutTagWithELSingleEvalTest.html
new file mode 100644
index 000000000..229f04f06
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/PutTagWithELSingleEvalTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put Tag using EL with Single Evaluation Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put Tag using EL with Single Evaluation Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Put Tag using EL to test Single Evaluation</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>${requestScope.doNotShow}</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/PutTagWithELTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/PutTagWithELTest.html
new file mode 100644
index 000000000..239bc704c
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/PutTagWithELTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put Tag using EL Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put Tag Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Put Tag using EL</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>Body Content defined by and el</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/PutTagWithServletTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/PutTagWithServletTest.html
new file mode 100644
index 000000000..26988b36d
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/PutTagWithServletTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put Tag with Servlet as Template Test</title>
+</head>
+w<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put Tag with Servlet as Template Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Put Tag using a servlet mapping as a template</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/SetCurrentContainerTagTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/SetCurrentContainerTagTest.html
new file mode 100644
index 000000000..f34e709d7
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/SetCurrentContainerTagTest.html
@@ -0,0 +1,66 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>setCurrentContainer Tag Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">setCurrentContainer Tag Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test setCurrentContainer Tag</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This definition is from an alternate container.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/TilesDefinitionFilterTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/TilesDefinitionFilterTest.html
new file mode 100644
index 000000000..57f90bb34
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/TilesDefinitionFilterTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Tiles Definition Filter Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put Tag Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Tiles Definition Filter</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This Content should be wrapped with the standard layout.</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/TilesDispatchServletTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/TilesDispatchServletTest.html
new file mode 100644
index 000000000..c5b07cca1
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/TilesDispatchServletTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Tiles Dispatch Servlet Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put Tag Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=FreeMarker: Test Tiles Dispatch Servlet</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/WelcomePageTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/WelcomePageTest.html
new file mode 100644
index 000000000..3c257bd38
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/freemarker/WelcomePageTest.html
@@ -0,0 +1,50 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Registration Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Welcome Page Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTitle</td>
+	<td>Tiles 2 Test Application</td>
+	<td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>Tiles 2 Test Application</td>
+    <td></td>
+</tr>
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/CompositeDefinitionWithInnerConfiguredDefinitionNoTypeTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/CompositeDefinitionWithInnerConfiguredDefinitionNoTypeTest.html
new file mode 100644
index 000000000..6c8ed08cf
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/CompositeDefinitionWithInnerConfiguredDefinitionNoTypeTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Composite Definition with Inner Configured Definition with no Type Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Composite Definition with Inner Configured Definition with no Type Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Insert Definition that contains another definition inside (configured via tiles-defs.xml) using JSP tags without types</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a composite definition with tags.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a configured inner definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/CompositeDefinitionWithInnerConfiguredDefinitionTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/CompositeDefinitionWithInnerConfiguredDefinitionTest.html
new file mode 100644
index 000000000..59e3dc68f
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/CompositeDefinitionWithInnerConfiguredDefinitionTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Composite Definition with Inner Configured Definition Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Composite Definition with Inner Configured Definition Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Insert Definition that contains another definition inside (configured via tiles-defs.xml) using JSP tags</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a composite definition with tags.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a configured inner definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/CompositeDefinitionWithInnerDefinitionNoTypeTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/CompositeDefinitionWithInnerDefinitionNoTypeTest.html
new file mode 100644
index 000000000..1542eebcf
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/CompositeDefinitionWithInnerDefinitionNoTypeTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Composite Definition with Inner Configured Definition with no Type Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Composite Definition with Inner Configured Definition with no Type Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Insert Definition that contains another definition inside using JSP tags without types</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a composite definition with tags.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is an inner definition with tags.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/CompositeDefinitionWithInnerDefinitionTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/CompositeDefinitionWithInnerDefinitionTest.html
new file mode 100644
index 000000000..3fc1f3d98
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/CompositeDefinitionWithInnerDefinitionTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Composite Definition with Inner Definition Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Composite Definition with Inner Definition Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Insert Definition that contains another definition inside using JSP tags</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a composite definition with tags.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is an inner definition with tags.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredCompositeDefinitionTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredCompositeDefinitionTest.html
new file mode 100644
index 000000000..d468819e3
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredCompositeDefinitionTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Composite Definition Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+w<tr><td rowspan="1" colspan="3">Configured Composite Definition Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Insert Configured Definition that contains another definition inside</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a configured composite definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a configured inner definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionAttributePreparerTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionAttributePreparerTest.html
new file mode 100644
index 000000000..2518b890f
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionAttributePreparerTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Attribute Preparer Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Attribute Preparer Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Insert Configured Definition with Attribute Preparer</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the value added by the AttributeViewPreparer</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionAttributeRolesTagsTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionAttributeRolesTagsTest.html
new file mode 100644
index 000000000..50f545692
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionAttributeRolesTagsTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Attribute Roles Tags Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Attribute Roles Tags Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Insert Configured Definition with Attribute that have Roles in Tags</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextNotPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionAttributeRolesTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionAttributeRolesTest.html
new file mode 100644
index 000000000..a002826b1
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionAttributeRolesTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Attribute Roles Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Attribute Roles Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Insert Configured Definition with Attribute that have Roles</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextNotPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionCascadedListTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionCascadedListTest.html
new file mode 100644
index 000000000..cf92053ea
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionCascadedListTest.html
@@ -0,0 +1,76 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Cascaded List Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Cascaded List Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Insert Configured Cascaded Definition with List</td>
+	<td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the title.</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the header</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>Single attribute "stringTest" value: This is a string </td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>valueOne</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>valueTwo</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>valueThree</td>
+    <td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionCascadedOverriddenTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionCascadedOverriddenTest.html
new file mode 100644
index 000000000..2104bbcdd
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionCascadedOverriddenTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Cascaded Overridden Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Cascaded Overridden Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Insert Configured Cascaded Definition with Override</td>
+	<td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the title.</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the header</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is a body</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is a configured inner definition.</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the header</td>
+    <td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionCascadedTemplateTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionCascadedTemplateTest.html
new file mode 100644
index 000000000..8cfa6c635
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionCascadedTemplateTest.html
@@ -0,0 +1,56 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Cascaded Template Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Cascaded Template Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Insert Configured Cascaded Definition with Template</td>
+	<td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the title.</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the header</td>
+    <td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionCascadedTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionCascadedTest.html
new file mode 100644
index 000000000..df76a0082
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionCascadedTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Cascaded Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Cascaded Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Insert Configured Cascaded Definition</td>
+	<td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the title.</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the header</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is a body</td>
+    <td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionDbTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionDbTest.html
new file mode 100644
index 000000000..9a67094df
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionDbTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Db Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Db Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Insert Configured Definition from DB</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionDefaultValuesTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionDefaultValuesTest.html
new file mode 100644
index 000000000..086df4985
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionDefaultValuesTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition with Default Values Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition with Default Values Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Insert Configured Definition with Default Values</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the alternate header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the default body in the tag.</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionELSingleEvalTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionELSingleEvalTest.html
new file mode 100644
index 000000000..7b45830c8
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionELSingleEvalTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition EL with Single Evaluation Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition EL with Single Evaluation Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Insert Configured Definition with EL to test Single Evaluation</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a configured definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>${requestScope.doNotShow}</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionELTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionELTest.html
new file mode 100644
index 000000000..a6fce3311
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionELTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition EL Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition EL Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Insert Configured Definition with EL</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a configured composite definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a configured inner definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionExceptionTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionExceptionTest.html
new file mode 100644
index 000000000..87da57af7
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionExceptionTest.html
@@ -0,0 +1,51 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition with Exception Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Insert Configured Definition with an exception in an attribute page</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextNotPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionExtendedDbTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionExtendedDbTest.html
new file mode 100644
index 000000000..67c12c4b2
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionExtendedDbTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Extended Db Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Extended Db Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Insert Extended Configured Definition from DB</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is an extended definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionFlushTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionFlushTest.html
new file mode 100644
index 000000000..8d334d52f
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionFlushTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition with Flush Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition with Flush Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Insert Configured Definition with Flush</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionFromClasspathTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionFromClasspathTest.html
new file mode 100644
index 000000000..0bf3c8c3b
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionFromClasspathTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition from Classpath Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition from Classpath Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Insert Configured Classpath Definition</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This tile was loaded from the classpath</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionIgnoreTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionIgnoreTest.html
new file mode 100644
index 000000000..0ad769c96
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionIgnoreTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Ignore Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Ignore Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Insert Configured Definition with Ignore</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextNotPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionInModuleTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionInModuleTest.html
new file mode 100644
index 000000000..c82a53ff3
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionInModuleTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition in Module Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition in Module Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Insert Configured Definition in Module</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This definition is from an alternate container.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This body is loaded from the "alt" module.</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionInlineTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionInlineTest.html
new file mode 100644
index 000000000..82454b274
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionInlineTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition with Inline Content Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition with Inline Content Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Insert Configured Definition with an inline content</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is an inline content</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionMVELTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionMVELTest.html
new file mode 100644
index 000000000..fc0ddb0a8
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionMVELTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition MVEL Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition MVEL Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Insert Configured Definition with MVEL</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a configured composite definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a configured inner definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionOGNLTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionOGNLTest.html
new file mode 100644
index 000000000..0ccdee882
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionOGNLTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition OGNL Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition OGNL Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Insert Configured Definition with OGNL</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a configured composite definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a configured inner definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionOldFormatTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionOldFormatTest.html
new file mode 100644
index 000000000..6e0cf8a77
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionOldFormatTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Old Format Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Old Format Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Insert Configured Definition in Old Format</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a definition configured in 1.1 format.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionOpenBodyTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionOpenBodyTest.html
new file mode 100644
index 000000000..3ef469d95
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionOpenBodyTest.html
@@ -0,0 +1,66 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition with Open BodyTest</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition with Open Body Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Insert Configured Definition with Open Body</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is a customized context</td>
+    <td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionOverrideAndNotTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionOverrideAndNotTest.html
new file mode 100644
index 000000000..7084c970f
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionOverrideAndNotTest.html
@@ -0,0 +1,66 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition with Overridden Content Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition with Overridden and Original Content Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Insert Configured Definition with an overridden content and one with original content</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is an overridden content</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionOverrideTemplateTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionOverrideTemplateTest.html
new file mode 100644
index 000000000..6385866dc
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionOverrideTemplateTest.html
@@ -0,0 +1,66 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition with Overridden Template Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition with Overridden Template Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Insert Configured Definition with an overridden template</td>
+	<td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the overridden template.</td>
+    <td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionOverrideTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionOverrideTest.html
new file mode 100644
index 000000000..0e50fadef
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionOverrideTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition with Overridden Content Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition with Overridden Content Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Insert Configured Definition with an overridden content</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is an overridden content</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionRegexpTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionRegexpTest.html
new file mode 100644
index 000000000..5efe63907
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionRegexpTest.html
@@ -0,0 +1,76 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Regular Expression Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Regular Expression Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Insert Configured Definition with Regular Expression</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is layout one.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is layout two.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This definition has a message: Hello.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This definition has a message: Bye.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionReversedTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionReversedTest.html
new file mode 100644
index 000000000..93cb4a8cf
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionReversedTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Reversed Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Reversed Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Insert Configured Definition with Reversed Attribute</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>.eltit eht si sihT</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionRoleTagTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionRoleTagTest.html
new file mode 100644
index 000000000..634d560b9
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionRoleTagTest.html
@@ -0,0 +1,66 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Role Tag Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Role Tag Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Insert Configured Definition with Specified Role in Tag</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This definition appears.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextNotPresent</td>
+	<td>This definition does not appear.</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionRoleTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionRoleTest.html
new file mode 100644
index 000000000..a908e1519
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionRoleTest.html
@@ -0,0 +1,66 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Role Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Role Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Insert Configured Definition with Specified Role</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This definition appears.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextNotPresent</td>
+	<td>This definition does not appear.</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionTest.html
new file mode 100644
index 000000000..091cbc4f2
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Insert Configured Definition</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionWildcardTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionWildcardTest.html
new file mode 100644
index 000000000..dced3f11d
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionWildcardTest.html
@@ -0,0 +1,76 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Wildcard Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Wildcard Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Insert Configured Definition with Wildcards</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is layout one.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is layout two.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This definition has a message: Hello.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This definition has a message: Bye.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionWithConfiguredPreparerTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionWithConfiguredPreparerTest.html
new file mode 100644
index 000000000..aa9877224
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionWithConfiguredPreparerTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition with Configured Preparer Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition with Configured Preparer Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Insert Configured Definition with Preparer configured in the definition itself</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the value added by the ViewPreparer</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionWithPreparerTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionWithPreparerTest.html
new file mode 100644
index 000000000..ca6dd76b6
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionWithPreparerTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition with Preparer Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition with Preparer Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Insert Configured Definition with Preparer</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the value added by the ViewPreparer</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionWithUnderscoresTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionWithUnderscoresTest.html
new file mode 100644
index 000000000..16fd184a6
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredDefinitionWithUnderscoresTest.html
@@ -0,0 +1,52 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Definition Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Definition Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test underscores without localization</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>Non localized definition</td>
+	<td></td>
+</tr>
+
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredNestedDefinitionTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredNestedDefinitionTest.html
new file mode 100644
index 000000000..02733dc2c
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredNestedDefinitionTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Nested Definition Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Nested Definition Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Insert Nested Definition</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a nested definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredNestedListDefinitionTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredNestedListDefinitionTest.html
new file mode 100644
index 000000000..c76e4ecf1
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ConfiguredNestedListDefinitionTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Configured Nested List Definition Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Configured Nested List Definition Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Insert Nested List Definition</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a nested definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/DefinitionTagExtendTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/DefinitionTagExtendTest.html
new file mode 100644
index 000000000..7688ff426
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/DefinitionTagExtendTest.html
@@ -0,0 +1,60 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Definition Tag Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Definition Tag Extend Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+    <td>clickAndWait</td>
+    <td>link=Velocity: Test Definition Tag extending configured and custom definitions</td>
+    <td></td>
+    </tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is an overridden title</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the header</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is an overridden content</td>
+    <td></td>
+</tr>
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/DefinitionTagListInheritTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/DefinitionTagListInheritTest.html
new file mode 100644
index 000000000..7a0292189
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/DefinitionTagListInheritTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Definition Tag List Inherit Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Definition Tag List Inherit Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Definition Tag with a List Inherit</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>Single attribute "stringTest" value: This is a string </td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueOne</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueTwo</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueThree</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueFour</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/DefinitionTagPreparerTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/DefinitionTagPreparerTest.html
new file mode 100644
index 000000000..779a5aa3f
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/DefinitionTagPreparerTest.html
@@ -0,0 +1,62 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ *
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Definition Tag with Preparer Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Definition Tag with Preparer Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Definition Tag with Preparer</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the value added by the ViewPreparer</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/DefinitionTagTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/DefinitionTagTest.html
new file mode 100644
index 000000000..251a3340a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/DefinitionTagTest.html
@@ -0,0 +1,60 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Definition Tag Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Definition Tag Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+    <td>clickAndWait</td>
+    <td>link=Velocity: Test Definition Tag</td>
+    <td></td>
+    </tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the title</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the header</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is a body</td>
+    <td></td>
+</tr>
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ImportAttributeTagAllTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ImportAttributeTagAllTest.html
new file mode 100644
index 000000000..7504f47df
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ImportAttributeTagAllTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Import Attribute Tag with no Name Specified Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Import Attribute Tag with no Name Specified Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test importAttribute Tag with no name</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>One</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>Two</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>Three </td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ImportAttributeTagInheritTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ImportAttributeTagInheritTest.html
new file mode 100644
index 000000000..66fdb6b54
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ImportAttributeTagInheritTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Import Attribute Tag Inherit Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Import Attribute Tag Inherit Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test importAttribute Tag with List Inherit</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>Single attribute "stringTest" value: This is a string </td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueOne</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueTwo</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueThree</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueFour</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ImportAttributeTagTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ImportAttributeTagTest.html
new file mode 100644
index 000000000..5a96b5e6d
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/ImportAttributeTagTest.html
@@ -0,0 +1,66 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Import Attribute Tag Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Import Attribute Tag Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test importAttribute Tag</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>Single attribute "stringTest" value: This is a string </td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueOne</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueTwo</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueThree</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/LocalizationTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/LocalizationTest.html
new file mode 100644
index 000000000..45c4a82fb
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/LocalizationTest.html
@@ -0,0 +1,141 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put Tag Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Localization Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Localization</td>
+	<td></td>
+</tr>
+<tr>
+	<td>storeText</td>
+	<td>defaultLocaleMessage</td>
+	<td>localeMessage</td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>//input[@value='Submit']</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertText</td>
+	<td>defaultLocaleMessage</td>
+	<td>${localeMessage}</td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Select another locale</td>
+	<td></td>
+</tr>
+<tr>
+	<td>select</td>
+	<td>locale</td>
+	<td>label=American English</td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>//input[@value='Submit']</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>American English locale</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Select another locale</td>
+	<td></td>
+</tr>
+<tr>
+	<td>select</td>
+	<td>locale</td>
+	<td>label=British English</td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>//input[@value='Submit']</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>British English locale</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Select another locale</td>
+	<td></td>
+</tr>
+<tr>
+	<td>select</td>
+	<td>locale</td>
+	<td>label=French</td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>//input[@value='Submit']</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>French locale</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Select another locale</td>
+	<td></td>
+</tr>
+<tr>
+	<td>select</td>
+	<td>locale</td>
+	<td>label=Italian</td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>//input[@value='Submit']</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>Italian locale</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/PutListCascadedTagTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/PutListCascadedTagTest.html
new file mode 100644
index 000000000..389109d08
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/PutListCascadedTagTest.html
@@ -0,0 +1,76 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put List Cascaded Tag Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put List Cascaded Tag Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Put List Cascaded Tag</td>
+	<td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the title.</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the header</td>
+    <td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>Single attribute "stringTest" value: This is a string </td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueOne</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueTwo</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueThree</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/PutListTagInheritTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/PutListTagInheritTest.html
new file mode 100644
index 000000000..9a5ed43ed
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/PutListTagInheritTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put List Tag Inherit Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put List Tag Inherit Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Put List Tag with Inherit</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>Single attribute "stringTest" value: This is a string </td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueOne</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueTwo</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueThree</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueFour</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/PutListTagTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/PutListTagTest.html
new file mode 100644
index 000000000..9136866e3
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/PutListTagTest.html
@@ -0,0 +1,66 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put List Tag Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put Tag Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Put List Tag</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>Single attribute "stringTest" value: This is a string </td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueOne</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueTwo</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>valueThree</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/PutTagCascadedOverriddenTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/PutTagCascadedOverriddenTest.html
new file mode 100644
index 000000000..f3bffbd87
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/PutTagCascadedOverriddenTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put Tag Cascaded Overridden Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put Tag Cascaded Overridden Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Put Tag with Overridden Cascaded Attributes</td>
+	<td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the title.</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the header</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is a body</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is a configured inner definition.</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the header</td>
+    <td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/PutTagCascadedTemplateTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/PutTagCascadedTemplateTest.html
new file mode 100644
index 000000000..8e1b11a10
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/PutTagCascadedTemplateTest.html
@@ -0,0 +1,56 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put Tag Cascaded Template Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put Tag Cascaded Template Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Put Tag with Cascaded Attributes and Template</td>
+	<td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the title.</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the header</td>
+    <td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/PutTagCascadedTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/PutTagCascadedTest.html
new file mode 100644
index 000000000..c45c7b5eb
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/PutTagCascadedTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put Tag Cascaded Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put Tag Cascaded Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Put Tag with Cascaded Attributes</td>
+	<td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the title.</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is the header</td>
+    <td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>This is a body</td>
+    <td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/PutTagFlushTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/PutTagFlushTest.html
new file mode 100644
index 000000000..ab3dbf5a1
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/PutTagFlushTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put Tag with Flush Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put Tag with Flush Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Put Tag with Flush</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/PutTagNestedDefinitionTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/PutTagNestedDefinitionTest.html
new file mode 100644
index 000000000..36fabd356
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/PutTagNestedDefinitionTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put Tag with Nested Definition Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put Tag with Nested Definition Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Insert Nested Definition only using JSP tags</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a nested definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/PutTagNestedListDefinitionTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/PutTagNestedListDefinitionTest.html
new file mode 100644
index 000000000..abcaf904a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/PutTagNestedListDefinitionTest.html
@@ -0,0 +1,71 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put Tag with Nested List Definition Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put Tag with Nested List Definition Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Insert Nested List Definition only using JSP tags</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a nested definition.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/PutTagReversedTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/PutTagReversedTest.html
new file mode 100644
index 000000000..0ab07d4b6
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/PutTagReversedTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put Tag Reversed Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put Tag Reversed Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Put Tag with Reversed Attribute</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>.eltit eht si sihT</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/PutTagTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/PutTagTest.html
new file mode 100644
index 000000000..2c02dc423
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/PutTagTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put Tag Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put Tag Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Put Tag</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/PutTagWithELSingleEvalTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/PutTagWithELSingleEvalTest.html
new file mode 100644
index 000000000..918f85601
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/PutTagWithELSingleEvalTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put Tag using EL with Single Evaluation Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put Tag using EL with Single Evaluation Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Put Tag using EL to test Single Evaluation</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>${requestScope.doNotShow}</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/PutTagWithELTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/PutTagWithELTest.html
new file mode 100644
index 000000000..323d38a8a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/PutTagWithELTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put Tag using EL Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put Tag Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Put Tag using EL</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>Body Content defined by and el</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/PutTagWithServletTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/PutTagWithServletTest.html
new file mode 100644
index 000000000..fd98087c4
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/PutTagWithServletTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Put Tag with Servlet as Template Test</title>
+</head>
+w<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put Tag with Servlet as Template Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Put Tag using a servlet mapping as a template</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/SetCurrentContainerTagTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/SetCurrentContainerTagTest.html
new file mode 100644
index 000000000..0fc68402a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/SetCurrentContainerTagTest.html
@@ -0,0 +1,66 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>setCurrentContainer Tag Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">setCurrentContainer Tag Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test setCurrentContainer Tag</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This definition is from an alternate container.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/TilesDefinitionFilterTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/TilesDefinitionFilterTest.html
new file mode 100644
index 000000000..a95131b08
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/TilesDefinitionFilterTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Tiles Definition Filter Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put Tag Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Tiles Definition Filter</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This Content should be wrapped with the standard layout.</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/TilesDispatchServletTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/TilesDispatchServletTest.html
new file mode 100644
index 000000000..7175978c7
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/TilesDispatchServletTest.html
@@ -0,0 +1,61 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Tiles Dispatch Servlet Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Put Tag Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>clickAndWait</td>
+	<td>link=Velocity: Test Tiles Dispatch Servlet</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the title.</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is the header</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTextPresent</td>
+	<td>This is a body</td>
+	<td></td>
+</tr>
+
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/WelcomePageTest.html b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/WelcomePageTest.html
new file mode 100644
index 000000000..3c257bd38
--- /dev/null
+++ b/Java-base/tiles/src/tiles-test-pom/tiles-test/src/test/selenium/velocity/WelcomePageTest.html
@@ -0,0 +1,50 @@
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>Registration Test</title>
+</head>
+<body>
+<table cellpadding="1" cellspacing="1" border="1">
+<thead>
+<tr><td rowspan="1" colspan="3">Welcome Page Test</td></tr>
+</thead><tbody>
+<tr>
+	<td>open</td>
+	<td>/tiles-test/index.jsp</td>
+	<td></td>
+</tr>
+<tr>
+	<td>assertTitle</td>
+	<td>Tiles 2 Test Application</td>
+	<td></td>
+</tr>
+<tr>
+    <td>assertTextPresent</td>
+    <td>Tiles 2 Test Application</td>
+    <td></td>
+</tr>
+</tbody></table>
+</body>
+</html>
diff --git a/Java-base/tiles/src/tiles-velocity/pom.xml b/Java-base/tiles/src/tiles-velocity/pom.xml
new file mode 100644
index 000000000..ad5a1e6ad
--- /dev/null
+++ b/Java-base/tiles/src/tiles-velocity/pom.xml
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <parent>
+    <artifactId>tiles-parent</artifactId>
+    <groupId>org.apache.tiles</groupId>
+    <version>3.1-SNAPSHOT</version>
+  </parent>
+
+  <modelVersion>4.0.0</modelVersion>
+  <artifactId>tiles-velocity</artifactId>
+  <packaging>jar</packaging>
+  <description>Velocity Support in Tiles</description>
+  <name>Tiles - Velocity Support</name>
+  <properties>
+      <!-- decrease this whenever possible -->
+      <checkstyle.maxAllowedViolations>1</checkstyle.maxAllowedViolations>
+  </properties>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.tiles.autotag.plugin</groupId>
+        <artifactId>maven-autotag-plugin</artifactId>
+        <version>${tiles.autotag.version}</version>
+        <executions>
+            <execution>
+                <goals>
+                    <goal>generate-velocity</goal>
+                </goals>
+                <configuration>
+                    <packageName>org.apache.tiles.velocity.template</packageName>
+                    <requestClass>org.apache.tiles.request.Request</requestClass>
+                    <velocityRuntime>org.apache.tiles.request.velocity.autotag.VelocityAutotagRuntime</velocityRuntime>
+                </configuration>
+            </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.tiles</groupId>
+      <artifactId>tiles-servlet</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.tiles</groupId>
+      <artifactId>tiles-template</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>jcl-over-slf4j</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-jdk14</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>javax.servlet</groupId>
+      <artifactId>servlet-api</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.velocity</groupId>
+      <artifactId>velocity-tools</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>commons-digester</groupId>
+      <artifactId>commons-digester</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.easymock</groupId>
+      <artifactId>easymock</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.easymock</groupId>
+      <artifactId>easymockclassextension</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+        <groupId>org.apache.tiles</groupId>
+        <artifactId>tiles-request-velocity</artifactId>
+        <version>${tiles.request.version}</version>
+    </dependency>
+  </dependencies>
+</project>
diff --git a/Java-base/tiles/src/tiles-velocity/src/main/java/org/apache/tiles/velocity/TilesVelocityException.java b/Java-base/tiles/src/tiles-velocity/src/main/java/org/apache/tiles/velocity/TilesVelocityException.java
new file mode 100644
index 000000000..2faa0d81d
--- /dev/null
+++ b/Java-base/tiles/src/tiles-velocity/src/main/java/org/apache/tiles/velocity/TilesVelocityException.java
@@ -0,0 +1,72 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.velocity;
+
+import org.apache.tiles.TilesException;
+
+/**
+ * Exception connected to the usage of Velocity and Tiles.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public class TilesVelocityException extends TilesException {
+
+    /**
+     * Constructor.
+     *
+     * @since 2.2.0
+     */
+    public TilesVelocityException() {
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param message The message of the exception.
+     * @since 2.2.0
+     */
+    public TilesVelocityException(String message) {
+        super(message);
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param e The cause of the exception.
+     * @since 2.2.0
+     */
+    public TilesVelocityException(Throwable e) {
+        super(e);
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param message The message of the exception.
+     * @param e The cause of the exception.
+     * @since 2.2.0
+     */
+    public TilesVelocityException(String message, Throwable e) {
+        super(message, e);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-velocity/src/main/java/org/apache/tiles/velocity/package-info.java b/Java-base/tiles/src/tiles-velocity/src/main/java/org/apache/tiles/velocity/package-info.java
new file mode 100644
index 000000000..318c5973d
--- /dev/null
+++ b/Java-base/tiles/src/tiles-velocity/src/main/java/org/apache/tiles/velocity/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * $Id: package-info.java 1049711 2010-12-15 21:12:00Z apetrelli $
+ *
+ * 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.
+ */
+/**
+ * Classes to support Velocity under a servlet environment in Tiles.
+ */
+package org.apache.tiles.velocity;
diff --git a/Java-base/tiles/src/tiles-velocity/src/main/java/org/apache/tiles/velocity/template/AbstractDefaultToStringRenderable.java b/Java-base/tiles/src/tiles-velocity/src/main/java/org/apache/tiles/velocity/template/AbstractDefaultToStringRenderable.java
new file mode 100644
index 000000000..2f76d6842
--- /dev/null
+++ b/Java-base/tiles/src/tiles-velocity/src/main/java/org/apache/tiles/velocity/template/AbstractDefaultToStringRenderable.java
@@ -0,0 +1,124 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.velocity.template;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.tiles.velocity.TilesVelocityException;
+import org.apache.velocity.context.Context;
+import org.apache.velocity.exception.MethodInvocationException;
+import org.apache.velocity.exception.ParseErrorException;
+import org.apache.velocity.exception.ResourceNotFoundException;
+import org.apache.velocity.runtime.Renderable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Renderable that provides a default implementation of {@link Renderable#toString()}
+ * and allows access to parameters and context objects.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public abstract class AbstractDefaultToStringRenderable implements Renderable {
+
+
+    /**
+     * The Velocity context.
+     *
+     * @since 2.2.0
+     */
+    protected final Context velocityContext;
+
+    /**
+     * The parameters used in the current tool call.
+     *
+     * @since 2.2.0
+     */
+    protected final Map<String, Object> params;
+
+    /**
+     * The HTTP response.
+     *
+     * @since 2.2.0
+     */
+    protected final HttpServletResponse response;
+
+    /**
+     * The HTTP request.
+     *
+     * @since 2.2.0
+     */
+    protected final HttpServletRequest request;
+
+    /**
+     * The logging object.
+     */
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    /**
+     * Constructor.
+     *
+     * @param velocityContext The Velocity context.
+     * @param params The parameters used in the current tool call.
+     * @param response The HTTP response.
+     * @param request The HTTP request.
+     * @since 2.2.0
+     */
+    public AbstractDefaultToStringRenderable(Context velocityContext,
+            Map<String, Object> params, HttpServletResponse response,
+            HttpServletRequest request) {
+        this.velocityContext = velocityContext;
+        this.params = params;
+        this.response = response;
+        this.request = request;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public String toString() {
+        StringWriter writer = new StringWriter();
+        try {
+            render(null, writer);
+        } catch (MethodInvocationException e) {
+            throw new TilesVelocityException("Cannot invoke method when rendering", e);
+        } catch (ParseErrorException e) {
+            throw new TilesVelocityException("Cannot parse when rendering", e);
+        } catch (ResourceNotFoundException e) {
+            throw new TilesVelocityException("Cannot find resource when rendering", e);
+        } catch (IOException e) {
+            throw new TilesVelocityException("I/O exception when rendering", e);
+        } finally {
+            try {
+                writer.close();
+            } catch (IOException e) {
+                log.error("Error when closing a StringWriter, the impossible happened!", e);
+            }
+        }
+        return writer.toString();
+    }
+}
diff --git a/Java-base/tiles/src/tiles-velocity/src/main/java/org/apache/tiles/velocity/template/ContextHolder.java b/Java-base/tiles/src/tiles-velocity/src/main/java/org/apache/tiles/velocity/template/ContextHolder.java
new file mode 100644
index 000000000..80b0d3fee
--- /dev/null
+++ b/Java-base/tiles/src/tiles-velocity/src/main/java/org/apache/tiles/velocity/template/ContextHolder.java
@@ -0,0 +1,158 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.velocity.template;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.context.Context;
+
+/**
+ * An object that holds the current state of Velocity in a Servlet environment.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public class ContextHolder {
+
+    /**
+     * The Velocity context.
+     */
+    private Context velocityContext;
+
+    /**
+     * The HTTP request.
+     */
+    private HttpServletRequest request;
+
+    /**
+     * The HTTP response.
+     */
+    private HttpServletResponse response;
+
+    /**
+     * The servlet context.
+     */
+    private ServletContext application;
+
+    /**
+     * Sets the current {@link HttpServletRequest}. This is required for this
+     * tool to operate and will throw a NullPointerException if this is not set
+     * or is set to {@code null}.
+     *
+     * @param request The HTTP request.
+     * @since 2.2.0
+     */
+    public void setRequest(HttpServletRequest request) {
+        if (request == null) {
+            throw new NullPointerException("request should not be null");
+        }
+        this.request = request;
+    }
+
+    /**
+     * Sets the current {@link HttpServletResponse}. This is required for this
+     * tool to operate and will throw a NullPointerException if this is not set
+     * or is set to {@code null}.
+     *
+     * @param response The HTTP response.
+     * @since 2.2.0
+     */
+    public void setResponse(HttpServletResponse response) {
+        if (response == null) {
+            throw new NullPointerException("response should not be null");
+        }
+        this.response = response;
+    }
+
+    /**
+     * Sets the {@link ServletContext}. This is required for this tool to
+     * operate and will throw a NullPointerException if this is not set or is
+     * set to {@code null}.
+     *
+     * @param application The Servlet context.
+     * @since 2.2.0
+     */
+    public void setServletContext(ServletContext application) {
+        if (application == null) {
+            throw new NullPointerException("servlet context should not be null");
+        }
+        this.application = application;
+    }
+
+    /**
+     * Sets the Velocity {@link Context}. This is required for this tool to
+     * operate and will throw a NullPointerException if this is not set or is
+     * set to {@code null}.
+     *
+     * @param context The Velocity context.
+     * @since 2.2.0
+     */
+    public void setVelocityContext(Context context) {
+        if (context == null) {
+            throw new NullPointerException(
+                    "velocity context should not be null");
+        }
+        this.velocityContext = context;
+    }
+
+    /**
+     * Returns the HTTP request.
+     *
+     * @return The HTTP request.
+     * @since 2.2.0
+     */
+    protected HttpServletRequest getRequest() {
+        return request;
+    }
+
+    /**
+     * Returns the HTTP response.
+     *
+     * @return The HTTP response.
+     * @since 2.2.0
+     */
+    protected HttpServletResponse getResponse() {
+        return response;
+    }
+
+    /**
+     * Returns the Servlet context.
+     *
+     * @return The Servlet context..
+     * @since 2.2.0
+     */
+    protected ServletContext getServletContext() {
+        return application;
+    }
+
+    /**
+     * Returns the Velocity context..
+     *
+     * @return The Velocity context.
+     * @since 2.2.0
+     */
+    protected Context getVelocityContext() {
+        return velocityContext;
+    }
+}
diff --git a/Java-base/tiles/src/tiles-velocity/src/main/java/org/apache/tiles/velocity/template/VelocityStyleTilesTool.java b/Java-base/tiles/src/tiles-velocity/src/main/java/org/apache/tiles/velocity/template/VelocityStyleTilesTool.java
new file mode 100644
index 000000000..e70db951d
--- /dev/null
+++ b/Java-base/tiles/src/tiles-velocity/src/main/java/org/apache/tiles/velocity/template/VelocityStyleTilesTool.java
@@ -0,0 +1,247 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.velocity.template;
+
+import java.io.IOException;
+import java.io.Writer;
+
+import javax.servlet.ServletContext;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.AttributeContext;
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.access.TilesAccess;
+import org.apache.tiles.request.Request;
+import org.apache.tiles.request.servlet.ServletUtil;
+import org.apache.tiles.request.velocity.VelocityRequest;
+import org.apache.velocity.context.InternalContextAdapter;
+import org.apache.velocity.runtime.Renderable;
+
+/**
+ * Tiles Tool to be used "the classic way".
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public class VelocityStyleTilesTool extends ContextHolder {
+
+    /**
+     * Returns an attribute.
+     *
+     * @param key The name of the attribute to get.
+     * @return The Attribute.
+     * @since 2.2.0
+     */
+    public Attribute get(String key) {
+        Request velocityRequest = createVelocityRequest(getServletContext(),
+                null);
+        TilesContainer container = TilesAccess.getCurrentContainer(velocityRequest);
+        AttributeContext attributeContext = container
+                .getAttributeContext(velocityRequest);
+        Attribute attribute = attributeContext.getAttribute(key);
+        return attribute;
+    }
+
+    /**
+     * Creates a new empty attribute.
+     *
+     * @return The created attribute.
+     * @since 2.2.0
+     */
+    public Attribute createAttribute() {
+        return new Attribute();
+    }
+
+    /**
+     * Creates an attribute that is a copy of the one passed as a parameter.
+     *
+     * @param attribute The attribute to copy.
+     * @return The copied attribute.
+     * @since 2.2.0
+     */
+    public Attribute clone(Attribute attribute) {
+        return new Attribute(attribute);
+    }
+
+    /**
+     * Creates an attribute that represents a template.
+     *
+     * @param template The template.
+     * @return The attribute.
+     * @since 2.2.0
+     */
+    public Attribute createTemplateAttribute(String template) {
+        return Attribute.createTemplateAttribute(template);
+    }
+
+    /**
+     * Renders an attribute.
+     *
+     * @param attribute The attribute to render.
+     * @return The renderable object, ready to be rendered.
+     * @since 2.2.0
+     */
+    public Renderable render(final Attribute attribute) {
+        return new AbstractDefaultToStringRenderable(getVelocityContext(),
+                null, getResponse(), getRequest()) {
+
+            public boolean render(InternalContextAdapter context, Writer writer)
+                    throws IOException {
+                Request velocityRequest = createVelocityRequest(
+                        getServletContext(), writer);
+                TilesContainer container = TilesAccess
+                        .getCurrentContainer(velocityRequest);
+                container.render(attribute, velocityRequest);
+                return true;
+            }
+
+        };
+    }
+
+    /**
+     * Renders a definition. It can be used in conjunction with
+     * {@link #startAttributeContext()} and {@link #endAttributeContext()} to
+     * customize appearance.
+     *
+     * @param definitionName The name of the definition to render.
+     * @return The renderable that renders the definition.
+     * @since 2.2.0
+     */
+    public Renderable renderDefinition(final String definitionName) {
+        return new AbstractDefaultToStringRenderable(getVelocityContext(),
+                null, getResponse(), getRequest()) {
+
+            public boolean render(InternalContextAdapter context, Writer writer) {
+                Request velocityRequest = createVelocityRequest(
+                        getServletContext(), writer);
+                TilesContainer container = TilesAccess
+                        .getCurrentContainer(velocityRequest);
+                container.render(definitionName, velocityRequest);
+                return true;
+            }
+
+        };
+    }
+
+    /**
+     * Renders the current attribute context. It can be used in conjunction with
+     * {@link #startAttributeContext()} and {@link #endAttributeContext()} to
+     * customize appearance.
+     *
+     * @return The renderable that renders the current attribute context.
+     * @since 2.2.0
+     */
+    public Renderable renderAttributeContext() {
+        return new AbstractDefaultToStringRenderable(getVelocityContext(),
+                null, getResponse(), getRequest()) {
+
+            public boolean render(InternalContextAdapter context, Writer writer) {
+                Request velocityRequest = createVelocityRequest(
+                        getServletContext(), writer);
+                TilesContainer container = TilesAccess
+                        .getCurrentContainer(velocityRequest);
+                container.renderContext(velocityRequest);
+                return true;
+            }
+
+        };
+    }
+
+    /**
+     * Starts the attribute context. Remember to call
+     * {@link #endAttributeContext()} when finished!
+     *
+     * @return The started attribute context, ready to be customized.
+     * @since 2.2.0
+     */
+    public AttributeContext startAttributeContext() {
+        Request velocityRequest = createVelocityRequest(
+                getServletContext(), null);
+        TilesContainer container = TilesAccess
+                .getCurrentContainer(velocityRequest);
+        return container.startContext(velocityRequest);
+    }
+
+    /**
+     * Ends the current attribute context. To be called after
+     * {@link #startAttributeContext()}.
+     *
+     * @return The tool itself.
+     * @since 2.2.0
+     */
+    public VelocityStyleTilesTool endAttributeContext() {
+        Request velocityRequest = createVelocityRequest(getServletContext(),
+                null);
+        TilesContainer container = TilesAccess
+                .getCurrentContainer(velocityRequest);
+        container.endContext(velocityRequest);
+        return this;
+    }
+
+    /**
+     * Returns the current attribute context.
+     *
+     * @return The current attribute context.
+     * @since 2.2.0
+     */
+    public AttributeContext getAttributeContext() {
+        Request velocityRequest = createVelocityRequest(
+                getServletContext(), null);
+        TilesContainer container = TilesAccess
+                .getCurrentContainer(velocityRequest);
+        return container.getAttributeContext(velocityRequest);
+    }
+
+    /**
+     * Sets the current container for the current request.
+     *
+     * @param containerKey The key of the container to set as "current" for the current request.
+     * @return The tool itself.
+     * @since 2.2.0
+     */
+    public VelocityStyleTilesTool setCurrentContainer(String containerKey) {
+        Request velocityRequest = createVelocityRequest(
+                getServletContext(), null);
+        TilesAccess.setCurrentContainer(velocityRequest, containerKey);
+        return this;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    public String toString() {
+        return "";
+    }
+
+    /**
+     * Creates a Velocity request.
+     *
+     * @param servletContext The servlet context.
+     * @param writer The writer.
+     * @return The created request.
+     */
+    protected Request createVelocityRequest(
+            ServletContext servletContext, Writer writer) {
+        return VelocityRequest.createVelocityRequest(ServletUtil
+                .getApplicationContext(servletContext), getRequest(),
+                getResponse(), getVelocityContext(), writer);
+    }
+}
diff --git a/Java-base/tiles/src/tiles-velocity/src/main/java/org/apache/tiles/velocity/template/package-info.java b/Java-base/tiles/src/tiles-velocity/src/main/java/org/apache/tiles/velocity/template/package-info.java
new file mode 100644
index 000000000..55f4f6f9d
--- /dev/null
+++ b/Java-base/tiles/src/tiles-velocity/src/main/java/org/apache/tiles/velocity/template/package-info.java
@@ -0,0 +1,24 @@
+/*
+ * $Id: package-info.java 1049711 2010-12-15 21:12:00Z apetrelli $
+ *
+ * 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.
+ */
+/**
+ * Classes that allow the use of "Tiles template" as a Velocity tool.
+ */
+package org.apache.tiles.velocity.template;
diff --git a/Java-base/tiles/src/tiles-velocity/src/main/resources/LICENSE.txt b/Java-base/tiles/src/tiles-velocity/src/main/resources/LICENSE.txt
new file mode 100644
index 000000000..d64569567
--- /dev/null
+++ b/Java-base/tiles/src/tiles-velocity/src/main/resources/LICENSE.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/Java-base/tiles/src/tiles-velocity/src/main/resources/META-INF/velocity.properties b/Java-base/tiles/src/tiles-velocity/src/main/resources/META-INF/velocity.properties
new file mode 100644
index 000000000..0280842b1
--- /dev/null
+++ b/Java-base/tiles/src/tiles-velocity/src/main/resources/META-INF/velocity.properties
@@ -0,0 +1,27 @@
+# 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.
+
+userdirective=org.apache.tiles.velocity.template.AddAttributeDirective,\
+  org.apache.tiles.velocity.template.AddListAttributeDirective,\
+  org.apache.tiles.velocity.template.DefinitionDirective,\
+  org.apache.tiles.velocity.template.GetAsStringDirective,\
+  org.apache.tiles.velocity.template.ImportAttributeDirective,\
+  org.apache.tiles.velocity.template.InsertAttributeDirective,\
+  org.apache.tiles.velocity.template.InsertDefinitionDirective,\
+  org.apache.tiles.velocity.template.InsertTemplateDirective,\
+  org.apache.tiles.velocity.template.PutAttributeDirective,\
+  org.apache.tiles.velocity.template.PutListAttributeDirective
diff --git a/Java-base/tiles/src/tiles-velocity/src/main/resources/NOTICE.txt b/Java-base/tiles/src/tiles-velocity/src/main/resources/NOTICE.txt
new file mode 100644
index 000000000..1f13ff856
--- /dev/null
+++ b/Java-base/tiles/src/tiles-velocity/src/main/resources/NOTICE.txt
@@ -0,0 +1,6 @@
+   Apache Tiles
+   Copyright 1999-2009 The Apache Software Foundation
+
+   This product includes software developed at
+   The Apache Software Foundation (http://www.apache.org/).
+
diff --git a/Java-base/tiles/src/tiles-velocity/src/main/resources/tools.xml b/Java-base/tiles/src/tiles-velocity/src/main/resources/tools.xml
new file mode 100644
index 000000000..65d673763
--- /dev/null
+++ b/Java-base/tiles/src/tiles-velocity/src/main/resources/tools.xml
@@ -0,0 +1,24 @@
+<?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.
+-->
+<tools>
+  <toolbox scope="request">
+    <tool key="tiles" class="org.apache.tiles.velocity.template.VelocityStyleTilesTool"/>
+  </toolbox>
+</tools>
diff --git a/Java-base/tiles/src/tiles-velocity/src/site/site.xml b/Java-base/tiles/src/tiles-velocity/src/site/site.xml
new file mode 100644
index 000000000..23a1b4659
--- /dev/null
+++ b/Java-base/tiles/src/tiles-velocity/src/site/site.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+/*
+ * $Id$
+ *
+ * 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.
+ */
+-->
+<project name="Apache Tiles - Velocity Support">
+     <skin>
+        <groupId>org.apache.maven.skins</groupId>
+        <artifactId>maven-fluido-skin</artifactId>
+        <version>1.3.0</version>
+     </skin>
+     <custom>
+        <fluidoSkin>
+        <topBarEnabled>true</topBarEnabled>
+        <sideBarEnabled>false</sideBarEnabled>
+        <searchEnabled>true</searchEnabled>
+        <gitHub>
+            <projectId>apache/tiles</projectId>
+            <ribbonOrientation>right</ribbonOrientation>
+            <ribbonColor>darkblue</ribbonColor>
+        </gitHub>
+        </fluidoSkin>
+     </custom>
+    <bannerLeft>
+        <name>Apache Tiles&#8482;</name>
+        <src>http://tiles.apache.org/images/logo.png</src>
+        <href>http://tiles.apache.org</href>
+    </bannerLeft>
+    <bannerRight>
+        <name>Apache Software Foundation</name>
+        <src>http://struts.apache.org/images/asf-logo.gif</src>
+        <href>http://www.apache.org</href>
+    </bannerRight>
+    <body>
+
+        <menu name="Apache Tiles&#8482;">
+            <item
+                   name="Welcome"
+                   href="../../index.html"/>
+            <item
+                    name="Tiles 3.0.x"
+                    href="../../framework/index.html"/>
+            <item
+                    name="Autotag 1.0.x"
+                    href="../../tiles-autotag/index.html"/>
+            <item
+                    name="Request 1.0.x"
+                    href="../../tiles-request/index.html"/>
+            <item
+                   name="Security bulletins"
+                   href="../security/index.html"/>
+            <item
+                   name="Download"
+                   href="http://tiles.apache.org/download.html"/>
+        </menu>
+
+        <menu ref="modules" />
+        <menu ref="reports" />
+
+        <footer>
+            <div class="row span12">
+                Apache Tiles, Tiles, Apache, the Apache feather logo, and the Apache Tiles
+                project logos are trademarks of The Apache Software Foundation.
+            </div>
+        </footer>
+    </body>
+</project>
diff --git a/Java-base/tiles/src/tiles-velocity/src/test/java/org/apache/tiles/velocity/TilesVelocityExceptionTest.java b/Java-base/tiles/src/tiles-velocity/src/test/java/org/apache/tiles/velocity/TilesVelocityExceptionTest.java
new file mode 100644
index 000000000..e933e150c
--- /dev/null
+++ b/Java-base/tiles/src/tiles-velocity/src/test/java/org/apache/tiles/velocity/TilesVelocityExceptionTest.java
@@ -0,0 +1,77 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.velocity;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+/**
+ * Tests {@link TilesVelocityException}.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TilesVelocityExceptionTest {
+
+    /**
+     * Test method for {@link TilesVelocityException#TilesVelocityException()}.
+     */
+    @Test
+    public void testTilesVelocityException() {
+        TilesVelocityException exception = new TilesVelocityException();
+        assertNull(exception.getMessage());
+        assertNull(exception.getCause());
+    }
+
+    /**
+     * Test method for {@link TilesVelocityException#TilesVelocityException(java.lang.String)}.
+     */
+    @Test
+    public void testTilesVelocityExceptionString() {
+        TilesVelocityException exception = new TilesVelocityException("my message");
+        assertEquals("my message", exception.getMessage());
+        assertNull(exception.getCause());
+    }
+
+    /**
+     * Test method for {@link TilesVelocityException#TilesVelocityException(java.lang.Throwable)}.
+     */
+    @Test
+    public void testTilesVelocityExceptionThrowable() {
+        Throwable cause = new Throwable();
+        TilesVelocityException exception = new TilesVelocityException(cause);
+        assertEquals(cause.toString(), exception.getMessage());
+        assertEquals(cause, exception.getCause());
+    }
+
+    /**
+     * Test method for {@link TilesVelocityException#TilesVelocityException(java.lang.String, java.lang.Throwable)}.
+     */
+    @Test
+    public void testTilesVelocityExceptionStringThrowable() {
+        Throwable cause = new Throwable();
+        TilesVelocityException exception = new TilesVelocityException("my message", cause);
+        assertEquals("my message", exception.getMessage());
+        assertEquals(cause, exception.getCause());
+    }
+
+}
diff --git a/Java-base/tiles/src/tiles-velocity/src/test/java/org/apache/tiles/velocity/template/AbstractDefaultToStringRenderableTest.java b/Java-base/tiles/src/tiles-velocity/src/test/java/org/apache/tiles/velocity/template/AbstractDefaultToStringRenderableTest.java
new file mode 100644
index 000000000..66a363976
--- /dev/null
+++ b/Java-base/tiles/src/tiles-velocity/src/test/java/org/apache/tiles/velocity/template/AbstractDefaultToStringRenderableTest.java
@@ -0,0 +1,180 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.velocity.template;
+
+import static org.junit.Assert.*;
+import static org.easymock.classextension.EasyMock.*;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.velocity.context.Context;
+import org.apache.velocity.context.InternalContextAdapter;
+import org.junit.Test;
+
+/**
+ * Tests {@link AbstractDefaultToStringRenderable}.
+ */
+public class AbstractDefaultToStringRenderableTest {
+
+    /**
+     * Test method for {@link org.apache.tiles.velocity.template.AbstractDefaultToStringRenderable
+     * #AbstractDefaultToStringRenderable(org.apache.velocity.context.Context,
+     * java.util.Map, javax.servlet.http.HttpServletResponse, javax.servlet.http.HttpServletRequest)}.
+     */
+    @Test
+    public void testAbstractDefaultToStringRenderable() {
+        Context velociContext = createMock(Context.class);
+        HttpServletRequest request = createMock(HttpServletRequest.class);
+        HttpServletResponse response = createMock(HttpServletResponse.class);
+        Map<String, Object> params = new HashMap<String, Object>();
+
+        replay(velociContext, request, response);
+        DefaultRenderable renderable = new DefaultRenderable(velociContext,
+                params, response, request);
+        assertEquals(velociContext, renderable.getVelocityContext());
+        assertEquals(request, renderable.getRequest());
+        assertEquals(response, renderable.getResponse());
+        assertEquals(params, renderable.getParams());
+        verify(velociContext, request, response);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.velocity.template.AbstractDefaultToStringRenderable#toString()}.
+     */
+    @Test
+    public void testToString() {
+        Context velociContext = createMock(Context.class);
+        HttpServletRequest request = createMock(HttpServletRequest.class);
+        HttpServletResponse response = createMock(HttpServletResponse.class);
+        Map<String, Object> params = new HashMap<String, Object>();
+        params.put("one", "value1");
+
+        replay(velociContext, request, response);
+        DefaultRenderable renderable = new DefaultRenderable(velociContext,
+                params, response, request);
+
+        assertEquals("Hello!", renderable.toString());
+        assertTrue(renderable.getWriter() instanceof StringWriter);
+        assertNull(renderable.getInternalContextAdapter());
+        verify(velociContext, request, response);
+    }
+
+    /**
+     * Mock class for AbstractDefaultToStringRenderable.
+     */
+    private static class DefaultRenderable extends AbstractDefaultToStringRenderable {
+
+        /**
+         * The internal context.
+         */
+        private InternalContextAdapter internalContextAdapter;
+
+        /**
+         * The writer.
+         */
+        private Writer writer;
+
+        /**
+         * Constructor.
+         *
+         * @param velocityContext The Velocity context.
+         * @param params The parameters used in the current tool call.
+         * @param response The HTTP response.
+         * @param request The HTTP request.
+         */
+        public DefaultRenderable(Context velocityContext,
+                Map<String, Object> params, HttpServletResponse response,
+                HttpServletRequest request) {
+            super(velocityContext, params, response, request);
+        }
+
+        /** {@inheritDoc} */
+        public boolean render(InternalContextAdapter context, Writer writer)
+                throws IOException {
+            this.internalContextAdapter = context;
+            this.writer = writer;
+            writer.write("Hello!");
+            return true;
+        }
+
+        /**
+         * Returns the Velocity context.
+         *
+         * @return The velocity context.
+         */
+        public Context getVelocityContext() {
+            return velocityContext;
+        }
+
+        /**
+         * Returns the parameters.
+         *
+         * @return The parameters.
+         */
+        public Map<String, Object> getParams() {
+            return params;
+        }
+
+        /**
+         * Returns the request.
+         *
+         * @return The request.
+         */
+        public HttpServletRequest getRequest() {
+            return request;
+        }
+
+        /**
+         * Returns the respnse.
+         *
+         * @return The response.
+         */
+        public HttpServletResponse getResponse() {
+            return response;
+        }
+
+        /**
+         * Returns the internal context.
+         *
+         * @return The internal context.
+         */
+        public InternalContextAdapter getInternalContextAdapter() {
+            return internalContextAdapter;
+        }
+
+        /**
+         * Returns the writer.
+         *
+         * @return The writer.
+         */
+        public Writer getWriter() {
+            return writer;
+        }
+    }
+}
diff --git a/Java-base/tiles/src/tiles-velocity/src/test/java/org/apache/tiles/velocity/template/VelocityStyleTilesToolTest.java b/Java-base/tiles/src/tiles-velocity/src/test/java/org/apache/tiles/velocity/template/VelocityStyleTilesToolTest.java
new file mode 100644
index 000000000..cfb4f534a
--- /dev/null
+++ b/Java-base/tiles/src/tiles-velocity/src/test/java/org/apache/tiles/velocity/template/VelocityStyleTilesToolTest.java
@@ -0,0 +1,403 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.velocity.template;
+
+import static org.easymock.EasyMock.eq;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.isA;
+import static org.easymock.classextension.EasyMock.createMock;
+import static org.easymock.classextension.EasyMock.replay;
+import static org.easymock.classextension.EasyMock.verify;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.AttributeContext;
+import org.apache.tiles.Expression;
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.access.TilesAccess;
+import org.apache.tiles.request.ApplicationAccess;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.velocity.VelocityRequest;
+import org.apache.velocity.context.Context;
+import org.apache.velocity.context.InternalContextAdapter;
+import org.apache.velocity.runtime.Renderable;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests {@link VelocityStyleTilesTool}.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public class VelocityStyleTilesToolTest {
+
+    /**
+     * The tool to test.
+     */
+    private VelocityStyleTilesTool tool;
+
+    /**
+     * The request object.
+     */
+    private HttpServletRequest request;
+
+    /**
+     * The response object.
+     */
+    private HttpServletResponse response;
+
+    /**
+     * The servlet context.
+     */
+    private ServletContext servletContext;
+
+    /**
+     * The current velocity context.
+     */
+    private Context velocityContext;
+
+    /**
+     * Sets up the tool to test.
+     *
+     * @since 2.2.0
+     */
+    @Before
+    public void setUp() {
+        tool = new VelocityStyleTilesTool();
+        request = createMock(HttpServletRequest.class);
+        response = createMock(HttpServletResponse.class);
+        velocityContext = createMock(Context.class);
+        servletContext = createMock(ServletContext.class);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.velocity.template.VelocityStyleTilesTool#get(java.lang.String)}.
+     */
+    @Test
+    public void testGetAttribute() {
+        TilesContainer container = createMock(TilesContainer.class);
+        AttributeContext attributeContext = createMock(AttributeContext.class);
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        Attribute attribute = new Attribute("myValue");
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+        Map<String, Object> applicationScope = new HashMap<String, Object>();
+        requestScope.put(TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME, container);
+
+        expect(request.getAttribute(TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME)).andReturn(container);
+        expect(applicationContext.getApplicationScope()).andReturn(applicationScope).anyTimes();
+        expect(servletContext.getAttribute(ApplicationAccess
+                .APPLICATION_CONTEXT_ATTRIBUTE)).andReturn(applicationContext)
+                .anyTimes();
+        expect(container.getAttributeContext(isA(VelocityRequest.class)))
+                .andReturn(attributeContext);
+        expect(attributeContext.getAttribute("myAttribute")).andReturn(attribute);
+
+        replay(velocityContext, request, response, servletContext, container,
+                attributeContext, applicationContext);
+        initializeTool();
+        assertEquals(attribute, tool.get("myAttribute"));
+        verify(velocityContext, request, response, servletContext, container,
+                attributeContext, applicationContext);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.velocity.template.VelocityStyleTilesTool#createAttribute()}.
+     */
+    @Test
+    public void testCreateAttribute() {
+        replay(velocityContext, request, response, servletContext);
+        initializeTool();
+        Attribute attribute =  tool.createAttribute();
+        assertNull(attribute.getValue());
+        assertNull(attribute.getRenderer());
+        assertNull(attribute.getExpressionObject());
+        verify(velocityContext, request, response, servletContext);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.velocity.template.VelocityStyleTilesTool
+     * #clone(org.apache.tiles.Attribute)}.
+     */
+    @Test
+    public void testCloneAttribute() {
+        Attribute attribute = new Attribute("myValue", Expression
+                .createExpression("myExpression", null), "myRole",
+                "myRendererName");
+
+        replay(velocityContext, request, response, servletContext);
+        initializeTool();
+        assertEquals(attribute, tool.clone(attribute));
+        verify(velocityContext, request, response, servletContext);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.velocity.template.VelocityStyleTilesTool
+     * #createTemplateAttribute(java.lang.String)}.
+     */
+    @Test
+    public void testCreateTemplateAttribute() {
+        replay(velocityContext, request, response, servletContext);
+        initializeTool();
+        Attribute attribute = tool.createTemplateAttribute("myTemplate");
+        assertEquals("myTemplate", attribute.getValue());
+        assertEquals("template", attribute.getRenderer());
+        verify(velocityContext, request, response, servletContext);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.velocity.template.VelocityStyleTilesTool
+     * #render(org.apache.tiles.Attribute)}.
+     * @throws IOException If something goes wrong.
+     */
+    @Test
+    public void testRenderAttribute() throws IOException {
+        TilesContainer container = createMock(TilesContainer.class);
+        InternalContextAdapter internalContextAdapter = createMock(InternalContextAdapter.class);
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        StringWriter writer = new StringWriter();
+        Attribute attribute = new Attribute("myValue");
+
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+        Map<String, Object> applicationScope = new HashMap<String, Object>();
+        requestScope.put(TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME, container);
+
+        expect(request.getAttribute(TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME)).andReturn(container);
+        expect(applicationContext.getApplicationScope()).andReturn(applicationScope).anyTimes();
+        expect(servletContext.getAttribute(ApplicationAccess
+                .APPLICATION_CONTEXT_ATTRIBUTE)).andReturn(applicationContext)
+                .anyTimes();
+        container.render(eq(attribute), isA(VelocityRequest.class));
+
+        replay(velocityContext, request, response, servletContext, container,
+                internalContextAdapter, applicationContext);
+        initializeTool();
+        Renderable renderable = tool.render(attribute);
+        renderable.render(internalContextAdapter, writer);
+        verify(velocityContext, request, response, servletContext, container,
+                internalContextAdapter, applicationContext);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.velocity.template.VelocityStyleTilesTool
+     * #renderDefinition(java.lang.String)}.
+     * @throws IOException If something goes wrong.
+     */
+    @Test
+    public void testRenderDefinition() throws IOException {
+        TilesContainer container = createMock(TilesContainer.class);
+        InternalContextAdapter internalContextAdapter = createMock(InternalContextAdapter.class);
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        StringWriter writer = new StringWriter();
+
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+        Map<String, Object> applicationScope = new HashMap<String, Object>();
+        requestScope.put(TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME, container);
+
+        expect(request.getAttribute(TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME)).andReturn(container);
+        expect(applicationContext.getApplicationScope()).andReturn(applicationScope).anyTimes();
+        expect(servletContext.getAttribute(ApplicationAccess
+                .APPLICATION_CONTEXT_ATTRIBUTE)).andReturn(applicationContext)
+                .anyTimes();
+        container.render(eq("myDefinition"), isA(VelocityRequest.class));
+
+        replay(velocityContext, request, response, servletContext, container,
+                internalContextAdapter, applicationContext);
+        initializeTool();
+        Renderable renderable = tool.renderDefinition("myDefinition");
+        renderable.render(internalContextAdapter, writer);
+        verify(velocityContext, request, response, servletContext, container,
+                internalContextAdapter, applicationContext);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.velocity.template.VelocityStyleTilesTool#renderAttributeContext()}.
+     * @throws IOException If something goes wrong.
+     */
+    @Test
+    public void testRenderAttributeContext() throws IOException {
+        TilesContainer container = createMock(TilesContainer.class);
+        InternalContextAdapter internalContextAdapter = createMock(InternalContextAdapter.class);
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        StringWriter writer = new StringWriter();
+
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+        Map<String, Object> applicationScope = new HashMap<String, Object>();
+        requestScope.put(TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME, container);
+
+        expect(request.getAttribute(TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME)).andReturn(container);
+        expect(applicationContext.getApplicationScope()).andReturn(applicationScope).anyTimes();
+        expect(servletContext.getAttribute(ApplicationAccess
+                .APPLICATION_CONTEXT_ATTRIBUTE)).andReturn(applicationContext)
+                .anyTimes();
+        container.renderContext(isA(VelocityRequest.class));
+
+        replay(velocityContext, request, response, servletContext, container,
+                internalContextAdapter, applicationContext);
+        initializeTool();
+        Renderable renderable = tool.renderAttributeContext();
+        renderable.render(internalContextAdapter, writer);
+        verify(velocityContext, request, response, servletContext, container,
+                internalContextAdapter, applicationContext);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.velocity.template.VelocityStyleTilesTool#startAttributeContext()}.
+     */
+    @Test
+    public void testStartAttributeContext() {
+        TilesContainer container = createMock(TilesContainer.class);
+        AttributeContext attributeContext = createMock(AttributeContext.class);
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+        Map<String, Object> applicationScope = new HashMap<String, Object>();
+        requestScope.put(TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME, container);
+
+        expect(request.getAttribute(TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME)).andReturn(container);
+        expect(applicationContext.getApplicationScope()).andReturn(applicationScope).anyTimes();
+        expect(servletContext.getAttribute(ApplicationAccess
+                .APPLICATION_CONTEXT_ATTRIBUTE)).andReturn(applicationContext)
+                .anyTimes();
+        expect(container.startContext(isA(VelocityRequest.class)))
+                .andReturn(attributeContext);
+
+        replay(velocityContext, request, response, servletContext, container,
+                attributeContext, applicationContext);
+        initializeTool();
+        assertEquals(attributeContext, tool.startAttributeContext());
+        verify(velocityContext, request, response, servletContext, container,
+                attributeContext, applicationContext);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.velocity.template.VelocityStyleTilesTool#endAttributeContext()}.
+     */
+    @Test
+    public void testEndAttributeContext() {
+        TilesContainer container = createMock(TilesContainer.class);
+        AttributeContext attributeContext = createMock(AttributeContext.class);
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+        Map<String, Object> applicationScope = new HashMap<String, Object>();
+        requestScope.put(TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME, container);
+
+        expect(request.getAttribute(TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME)).andReturn(container);
+        expect(applicationContext.getApplicationScope()).andReturn(applicationScope).anyTimes();
+        expect(servletContext.getAttribute(ApplicationAccess
+                .APPLICATION_CONTEXT_ATTRIBUTE)).andReturn(applicationContext)
+                .anyTimes();
+        container.endContext(isA(VelocityRequest.class));
+
+        replay(velocityContext, request, response, servletContext, container,
+                attributeContext, applicationContext);
+        initializeTool();
+        tool.endAttributeContext();
+        verify(velocityContext, request, response, servletContext, container,
+                attributeContext, applicationContext);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.velocity.template.VelocityStyleTilesTool#getAttributeContext()}.
+     */
+    @Test
+    public void testGetAttributeContext() {
+        TilesContainer container = createMock(TilesContainer.class);
+        AttributeContext attributeContext = createMock(AttributeContext.class);
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+        Map<String, Object> applicationScope = new HashMap<String, Object>();
+        requestScope.put(TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME, container);
+
+        expect(request.getAttribute(TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME)).andReturn(container);
+        expect(applicationContext.getApplicationScope()).andReturn(applicationScope).anyTimes();
+        expect(servletContext.getAttribute(ApplicationAccess
+                .APPLICATION_CONTEXT_ATTRIBUTE)).andReturn(applicationContext)
+                .anyTimes();
+        expect(container.getAttributeContext(isA(VelocityRequest.class)))
+                .andReturn(attributeContext);
+
+        replay(velocityContext, request, response, servletContext, container,
+                attributeContext, applicationContext);
+        initializeTool();
+        assertEquals(attributeContext, tool.getAttributeContext());
+        verify(velocityContext, request, response, servletContext, container,
+                attributeContext, applicationContext);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.velocity.template.VelocityStyleTilesTool
+     * #setCurrentContainer(java.lang.String)}.
+     */
+    @Test
+    public void testSetCurrentContainer() {
+        TilesContainer container = createMock(TilesContainer.class);
+        ApplicationContext applicationContext = createMock(ApplicationContext.class);
+        Map<String, Object> applicationScope = new HashMap<String, Object>();
+        applicationScope.put("myKey", container);
+
+        Map<String, Object> requestScope = new HashMap<String, Object>();
+        requestScope.put(TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME, container);
+        request.setAttribute(TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME, container);
+        expect(request.getAttribute(TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME)).andReturn(container);
+        expect(applicationContext.getApplicationScope()).andReturn(applicationScope).anyTimes();
+        expect(servletContext.getAttribute(ApplicationAccess
+                .APPLICATION_CONTEXT_ATTRIBUTE)).andReturn(applicationContext)
+                .anyTimes();
+
+        replay(velocityContext, request, response, servletContext, container, applicationContext);
+        initializeTool();
+        assertEquals(tool, tool.setCurrentContainer("myKey"));
+        assertEquals(container, requestScope.get(TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME));
+        verify(velocityContext, request, response, servletContext, container, applicationContext);
+    }
+
+    /**
+     * Test method for {@link org.apache.tiles.velocity.template.VelocityStyleTilesTool#toString()}.
+     */
+    @Test
+    public void testToString() {
+        assertEquals("", tool.toString());
+    }
+
+    /**
+     * Initializes the tool for the test.
+     */
+    private void initializeTool() {
+        tool.setRequest(request);
+        tool.setResponse(response);
+        tool.setServletContext(servletContext);
+        tool.setVelocityContext(velocityContext);
+    }
+}
diff --git a/Java/maven-war-plugin-AbstractArtifactStub_103/Dockerfile b/Java/maven-war-plugin-AbstractArtifactStub_103/Dockerfile
new file mode 100644
index 000000000..34955205a
--- /dev/null
+++ b/Java/maven-war-plugin-AbstractArtifactStub_103/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:maven-war-plugin
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+    && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+    && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+    && mv /tmp/buggy.java $BUGGY_PATH \
+    && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/maven-war-plugin-AbstractArtifactStub_103/buggy.java b/Java/maven-war-plugin-AbstractArtifactStub_103/buggy.java
new file mode 100644
index 000000000..6163fae79
--- /dev/null
+++ b/Java/maven-war-plugin-AbstractArtifactStub_103/buggy.java
@@ -0,0 +1,147 @@
+package org.apache.maven.plugins.war.stub;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.handler.ArtifactHandler;
+import org.apache.maven.artifact.handler.DefaultArtifactHandler;
+import org.apache.maven.artifact.versioning.VersionRange;
+import org.apache.maven.plugin.testing.stubs.ArtifactStub;
+
+public abstract class AbstractArtifactStub
+    extends ArtifactStub
+{
+    protected String basedir;
+
+    public AbstractArtifactStub( String _basedir )
+    {
+        basedir = _basedir;
+    }
+
+    public String getVersion()
+    {
+        return "0.0-Test";
+    }
+
+    @Override
+    public String getBaseVersion()
+    {
+        return getVersion();
+    }
+
+    public String getScope()
+    {
+        return Artifact.SCOPE_RUNTIME;
+    }
+
+    public VersionRange getVersionRange()
+    {
+        return VersionRange.createFromVersion( getVersion());
+    }
+
+    public boolean isOptional()
+    {
+        return false;
+    }
+
+    public ArtifactHandler getArtifactHandler()
+    {
+        return new DefaultArtifactHandler( getType() );
+    }
+
+    /*
+     * TODO: Copied from org/apache/maven/artifact/DefaultArtifact.java; Consider merging...
+     */
+/* TODO: Copied from org/apache/maven/artifact/DefaultArtifact.java; Consider merging... */
+public int compareTo(org.apache.maven.artifact.Artifact a) {
+    /* -- We need to support groupId=null (it is missing in DefaultArtifact.java) */
+    int result;
+    if (a.getGroupId() != null) {
+        result = getGroupId().compareTo(a.getGroupId());
+    } else {
+        result = (getGroupId() == null) ? 0 : -1;
+    }
+    /* -- */
+    if (result == 0) {
+        result = getArtifactId().compareTo(a.getArtifactId());
+        if (result == 0) {
+            result = getType().compareTo(a.getType());
+            if (result == 0) {
+                {
+                    {
+                        result = /* NPEX_NULL_EXP */
+                        getClassifier().compareTo(/* NPEX_NULL_EXP */
+                        a.getClassifier());
+                    }
+                }
+                if (result == 0) {
+                    // We don't consider the version range in the comparison, just the resolved version
+                    result = getVersion().compareTo(a.getVersion());
+                }
+            }
+        }
+    }
+    return result;
+}
+
+    /*
+     * TODO: Copied from org/apache/maven/artifact/DefaultArtifact.java; Consider merging...
+     */
+    public boolean equals( Object o )
+    {
+        if ( o == this )
+        {
+            return true;
+        }
+
+        if ( !( o instanceof Artifact ) )
+        {
+            return false;
+        }
+
+        Artifact a = (Artifact) o;
+
+        /* -- We need to support groupId=null (it is missing in DefaultArtifact.java) */
+        if ( a.getGroupId() == null ? ( getGroupId() != null ) : a.getGroupId().equals( getGroupId() ) )
+        {
+            return false;
+        }
+        else if ( !a.getArtifactId().equals( getArtifactId() ) )
+        {
+            return false;
+        }
+        else if ( !a.getVersion().equals( getVersion() ) )
+        {
+            return false;
+        }
+        else if ( !a.getType().equals( getType() ) )
+        {
+            return false;
+        }
+        else if ( a.getClassifier() == null ? getClassifier() != null : !a.getClassifier().equals( getClassifier() ) )
+        {
+            return false;
+        }
+
+        // We don't consider the version range in the comparison, just the resolved version
+
+        return true;
+    }
+}
diff --git a/Java/maven-war-plugin-AbstractArtifactStub_103/metadata.json b/Java/maven-war-plugin-AbstractArtifactStub_103/metadata.json
new file mode 100644
index 000000000..b68d55db7
--- /dev/null
+++ b/Java/maven-war-plugin-AbstractArtifactStub_103/metadata.json
@@ -0,0 +1,21 @@
+{
+  "language": "java",
+  "id": "maven-war-plugin-AbstractArtifactStub_103",
+  "buggyPath": ".",
+  "referencePath": null,
+  "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+  "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+  "categories": [
+    "safety",
+    "npe"
+  ],
+  "npe": {
+    "filepath": "src/test/java/org/apache/maven/plugins/war/stub/AbstractArtifactStub.java",
+    "line": 91,
+    "npe_method": "compareTo",
+    "deref_field": "getClassifier",
+    "npe_class": "AbstractArtifactStub",
+    "repo": "maven-war-plugin",
+    "bug_id": "AbstractArtifactStub_103"
+  }
+}
diff --git a/Java/maven-war-plugin-AbstractArtifactStub_103/npe.json b/Java/maven-war-plugin-AbstractArtifactStub_103/npe.json
new file mode 100644
index 000000000..02cda04e0
--- /dev/null
+++ b/Java/maven-war-plugin-AbstractArtifactStub_103/npe.json
@@ -0,0 +1,7 @@
+{
+    "filepath": "src/test/java/org/apache/maven/plugins/war/stub/AbstractArtifactStub.java",
+    "line": 91,
+    "npe_method": "compareTo",
+    "deref_field": "getClassifier",
+    "npe_class": "AbstractArtifactStub"
+}
\ No newline at end of file
diff --git a/Java/maven-war-plugin-AbstractArtifactStub_76/Dockerfile b/Java/maven-war-plugin-AbstractArtifactStub_76/Dockerfile
new file mode 100644
index 000000000..34955205a
--- /dev/null
+++ b/Java/maven-war-plugin-AbstractArtifactStub_76/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:maven-war-plugin
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+    && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+    && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+    && mv /tmp/buggy.java $BUGGY_PATH \
+    && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/maven-war-plugin-AbstractArtifactStub_76/buggy.java b/Java/maven-war-plugin-AbstractArtifactStub_76/buggy.java
new file mode 100644
index 000000000..314b71093
--- /dev/null
+++ b/Java/maven-war-plugin-AbstractArtifactStub_76/buggy.java
@@ -0,0 +1,148 @@
+package org.apache.maven.plugins.war.stub;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.handler.ArtifactHandler;
+import org.apache.maven.artifact.handler.DefaultArtifactHandler;
+import org.apache.maven.artifact.versioning.VersionRange;
+import org.apache.maven.plugin.testing.stubs.ArtifactStub;
+
+public abstract class AbstractArtifactStub
+    extends ArtifactStub
+{
+    protected String basedir;
+
+    public AbstractArtifactStub( String _basedir )
+    {
+        basedir = _basedir;
+    }
+
+    public String getVersion()
+    {
+        return "0.0-Test";
+    }
+
+    @Override
+    public String getBaseVersion()
+    {
+        return getVersion();
+    }
+
+    public String getScope()
+    {
+        return Artifact.SCOPE_RUNTIME;
+    }
+
+    public VersionRange getVersionRange()
+    {
+        return VersionRange.createFromVersion( getVersion());
+    }
+
+    public boolean isOptional()
+    {
+        return false;
+    }
+
+    public ArtifactHandler getArtifactHandler()
+    {
+        return new DefaultArtifactHandler( getType() );
+    }
+
+    /*
+     * TODO: Copied from org/apache/maven/artifact/DefaultArtifact.java; Consider merging...
+     */
+/* TODO: Copied from org/apache/maven/artifact/DefaultArtifact.java; Consider merging... */
+public int compareTo(org.apache.maven.artifact.Artifact a) {
+    /* -- We need to support groupId=null (it is missing in DefaultArtifact.java) */
+    int result;
+    {
+        result = getGroupId().compareTo(/* NPEX_NULL_EXP */
+        a.getGroupId());
+    }
+    /* -- */
+    if (result == 0) {
+        result = getArtifactId().compareTo(a.getArtifactId());
+        if (result == 0) {
+            result = getType().compareTo(a.getType());
+            if (result == 0) {
+                if (getClassifier() == null) {
+                    if (a.getClassifier() != null) {
+                        result = 1;
+                    }
+                } else if (a.getClassifier() != null) {
+                    result = getClassifier().compareTo(a.getClassifier());
+                } else {
+                    result = -1;
+                }
+                if (result == 0) {
+                    // We don't consider the version range in the comparison, just the resolved version
+                    result = getVersion().compareTo(a.getVersion());
+                }
+            }
+        }
+    }
+    return result;
+}
+
+    /*
+     * TODO: Copied from org/apache/maven/artifact/DefaultArtifact.java; Consider merging...
+     */
+    public boolean equals( Object o )
+    {
+        if ( o == this )
+        {
+            return true;
+        }
+
+        if ( !( o instanceof Artifact ) )
+        {
+            return false;
+        }
+
+        Artifact a = (Artifact) o;
+
+        /* -- We need to support groupId=null (it is missing in DefaultArtifact.java) */
+        if ( a.getGroupId() == null ? ( getGroupId() != null ) : a.getGroupId().equals( getGroupId() ) )
+        {
+            return false;
+        }
+        else if ( !a.getArtifactId().equals( getArtifactId() ) )
+        {
+            return false;
+        }
+        else if ( !a.getVersion().equals( getVersion() ) )
+        {
+            return false;
+        }
+        else if ( !a.getType().equals( getType() ) )
+        {
+            return false;
+        }
+        else if ( a.getClassifier() == null ? getClassifier() != null : !a.getClassifier().equals( getClassifier() ) )
+        {
+            return false;
+        }
+
+        // We don't consider the version range in the comparison, just the resolved version
+
+        return true;
+    }
+}
diff --git a/Java/maven-war-plugin-AbstractArtifactStub_76/metadata.json b/Java/maven-war-plugin-AbstractArtifactStub_76/metadata.json
new file mode 100644
index 000000000..42e10b7b6
--- /dev/null
+++ b/Java/maven-war-plugin-AbstractArtifactStub_76/metadata.json
@@ -0,0 +1,21 @@
+{
+  "language": "java",
+  "id": "maven-war-plugin-AbstractArtifactStub_76",
+  "buggyPath": ".",
+  "referencePath": null,
+  "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+  "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+  "categories": [
+    "safety",
+    "npe"
+  ],
+  "npe": {
+    "filepath": "src/test/java/org/apache/maven/plugins/war/stub/AbstractArtifactStub.java",
+    "line": 78,
+    "npe_method": "compareTo",
+    "deref_field": "getGroupId",
+    "npe_class": "AbstractArtifactStub",
+    "repo": "maven-war-plugin",
+    "bug_id": "AbstractArtifactStub_76"
+  }
+}
diff --git a/Java/maven-war-plugin-AbstractArtifactStub_76/npe.json b/Java/maven-war-plugin-AbstractArtifactStub_76/npe.json
new file mode 100644
index 000000000..b338e3e39
--- /dev/null
+++ b/Java/maven-war-plugin-AbstractArtifactStub_76/npe.json
@@ -0,0 +1,7 @@
+{
+    "filepath": "src/test/java/org/apache/maven/plugins/war/stub/AbstractArtifactStub.java",
+    "line": 78,
+    "npe_method": "compareTo",
+    "deref_field": "getGroupId",
+    "npe_class": "AbstractArtifactStub"
+}
\ No newline at end of file
diff --git a/Java/maven-war-plugin-AbstractWarExplodedMojoTest_104/Dockerfile b/Java/maven-war-plugin-AbstractWarExplodedMojoTest_104/Dockerfile
new file mode 100644
index 000000000..34955205a
--- /dev/null
+++ b/Java/maven-war-plugin-AbstractWarExplodedMojoTest_104/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:maven-war-plugin
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+    && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+    && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+    && mv /tmp/buggy.java $BUGGY_PATH \
+    && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/maven-war-plugin-AbstractWarExplodedMojoTest_104/buggy.java b/Java/maven-war-plugin-AbstractWarExplodedMojoTest_104/buggy.java
new file mode 100644
index 000000000..90dc65e98
--- /dev/null
+++ b/Java/maven-war-plugin-AbstractWarExplodedMojoTest_104/buggy.java
@@ -0,0 +1,304 @@
+package org.apache.maven.plugins.war;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.plugin.testing.stubs.ArtifactStub;
+import org.apache.maven.plugins.war.stub.MavenProjectArtifactsStub;
+import org.codehaus.plexus.util.FileUtils;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * @author Stephane Nicoll
+ */
+public abstract class AbstractWarExplodedMojoTest
+    extends AbstractWarMojoTest
+{
+
+    protected WarExplodedMojo mojo;
+
+    public void setUp()
+        throws Exception
+    {
+        super.setUp();
+        mojo = (WarExplodedMojo) lookupMojo( "exploded", getPomFile() );
+    }
+
+    /**
+     * Returns the pom configuration to use.
+     *
+     * @return the pom configuration
+     */
+    protected abstract File getPomFile();
+
+    /**
+     * Returns the test directory to use.
+     *
+     * @return the test directory
+     */
+    protected abstract File getTestDirectory();
+
+    /**
+     * Configures the exploded mojo for the specified test.
+     * 
+     * If the <tt>sourceFiles</tt> parameter is <tt>null</tt>, sample JSPs are created by default.
+     *
+     * @param testId the id of the test
+     * @param artifactStubs the dependencies (may be null)
+     * @param sourceFiles the source files to create (may be null)
+     * @return the webapp directory
+     * @throws Exception if an error occurs while configuring the mojo
+     */
+/**
+ * Configures the exploded mojo for the specified test.
+ *
+ * If the <tt>sourceFiles</tt> parameter is <tt>null</tt>, sample JSPs are created by default.
+ *
+ * @param testId
+ * 		the id of the test
+ * @param artifactStubs
+ * 		the dependencies (may be null)
+ * @param sourceFiles
+ * 		the source files to create (may be null)
+ * @return the webapp directory
+ * @throws Exception
+ * 		if an error occurs while configuring the mojo
+ */
+protected java.io.File setUpMojo(final java.lang.String testId, org.apache.maven.plugin.testing.stubs.ArtifactStub[] artifactStubs, java.lang.String[] sourceFiles) throws java.lang.Exception {
+    final org.apache.maven.plugins.war.stub.MavenProjectArtifactsStub project = new org.apache.maven.plugins.war.stub.MavenProjectArtifactsStub();
+    final java.io.File webAppDirectory = new java.io.File(getTestDirectory(), testId);
+    // Create the webapp sources
+    java.io.File webAppSource;
+    if (sourceFiles == null) {
+        webAppSource = createWebAppSource(testId);
+    } else {
+        webAppSource = createWebAppSource(testId, false);
+        for (java.lang.String sourceFile : sourceFiles) {
+            java.io.File sample = new java.io.File(webAppSource, sourceFile);
+            createFile(sample);
+        }
+    }
+    final java.io.File classesDir = createClassesDir(testId, true);
+    final java.io.File workDirectory = new java.io.File(getTestDirectory(), "/war/work-" + testId);
+    createDir(workDirectory);
+    {
+        for (org.apache.maven.plugin.testing.stubs.ArtifactStub artifactStub : /* NPEX_NULL_EXP */
+        artifactStubs) {
+            project.addArtifact(artifactStub);
+        }
+    }
+    configureMojo(mojo, new java.util.LinkedList<java.lang.String>(), classesDir, webAppSource, webAppDirectory, project);
+    setVariableValueToObject(mojo, "workDirectory", workDirectory);
+    return webAppDirectory;
+}
+
+    /**
+     * Configures the exploded mojo for the specified test.
+     *
+     * @param testId the id of the test
+     * @param artifactStubs the dependencies (may be null)
+     * @return the webapp directory
+     * @throws Exception if an error occurs while configuring the mojo
+     */
+    protected File setUpMojo( final String testId, ArtifactStub[] artifactStubs )
+        throws Exception
+    {
+        return setUpMojo( testId, artifactStubs, null );
+    }
+
+    /**
+     * Cleans up a directory.
+     *
+     * @param directory the directory to remove
+     * @throws IOException if an error occurred while removing the directory
+     */
+    protected void cleanDirectory( File directory )
+        throws IOException
+    {
+        if ( directory != null && directory.isDirectory() && directory.exists() )
+        {
+            FileUtils.deleteDirectory( directory );
+        }
+    }
+
+    /**
+     * Asserts the default content of the war based on the specified webapp directory.
+     *
+     * @param webAppDirectory the webapp directory
+     * @return a list of File objects that have been asserted
+     */
+    protected List<File> assertDefaultContent( File webAppDirectory )
+    {
+        // Validate content of the webapp
+        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
+        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
+
+        assertTrue( "source file not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
+        assertTrue( "source file not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
+
+        final List<File> content = new ArrayList<>();
+        content.add( expectedWebSourceFile );
+        content.add( expectedWebSource2File );
+
+        return content;
+    }
+
+    /**
+     * Asserts the web.xml file of the war based on the specified webapp directory.
+     *
+     * @param webAppDirectory the webapp directory
+     * @return a list with the web.xml File object
+     */
+    protected List<File> assertWebXml( File webAppDirectory )
+    {
+        File expectedWEBXMLFile = new File( webAppDirectory, "WEB-INF/web.xml" );
+        assertTrue( "web xml not found: " + expectedWEBXMLFile.toString(), expectedWEBXMLFile.exists() );
+
+        final List<File> content = new ArrayList<>();
+        content.add( expectedWEBXMLFile );
+
+        return content;
+    }
+
+    /**
+     * Asserts custom content of the war based on the specified webapp directory.
+     *
+     * @param webAppDirectory the webapp directory
+     * @param filePaths an array of file paths relative to the webapp directory
+     * @param customMessage a custom message if an assertion fails
+     * @return a list of File objects that have been inspected
+     */
+    protected List<File> assertCustomContent( File webAppDirectory, String[] filePaths, String customMessage )
+    {
+        final List<File> content = new ArrayList<>();
+        for ( String filePath : filePaths )
+        {
+            final File expectedFile = new File( webAppDirectory, filePath );
+            if ( customMessage != null )
+            {
+                assertTrue( customMessage + " - " + expectedFile.toString(), expectedFile.exists() );
+            }
+            else
+            {
+                assertTrue( "source file not found: " + expectedFile.toString(), expectedFile.exists() );
+            }
+            content.add( expectedFile );
+        }
+        return content;
+    }
+
+    /**
+     * Asserts that the webapp contains only the specified files.
+     *
+     * @param webAppDirectory the webapp directory
+     * @param expectedFiles the expected files
+     * @param filter an optional filter to ignore some resources
+     */
+    protected void assertWebAppContent( File webAppDirectory, List<File> expectedFiles, FileFilter filter )
+    {
+        final List<File> webAppContent = new ArrayList<>();
+        if ( filter != null )
+        {
+            buildFilesList( webAppDirectory, filter, webAppContent );
+        }
+        else
+        {
+            buildFilesList( webAppDirectory, new FileFilterImpl( webAppDirectory, null ), webAppContent );
+        }
+
+        // Now we have the files, sort them.
+        Collections.sort( expectedFiles );
+        Collections.sort( webAppContent );
+        assertEquals( "Invalid webapp content, expected " + expectedFiles.size() + "file(s) " + expectedFiles
+            + " but got " + webAppContent.size() + " file(s) " + webAppContent, expectedFiles, webAppContent );
+    }
+
+    /**
+     * Builds the list of files and directories from the specified dir.
+     * 
+     * Note that the filter is not used the usual way. If the filter does not accept the current file, it's not added
+     * but yet the subdirectories are added if any.
+     *
+     * @param dir the base directory
+     * @param filter the filter
+     * @param content the current content, updated recursively
+     */
+    private void buildFilesList( final File dir, FileFilter filter, final List<File> content )
+    {
+        final File[] files = dir.listFiles();
+
+        for ( File file : files )
+        {
+            // Add the file if the filter is ok with it
+            if ( filter.accept( file ) )
+            {
+                content.add( file );
+            }
+
+            // Even if the file is not accepted and is a directory, add it
+            if ( file.isDirectory() )
+            {
+                buildFilesList( file, filter, content );
+            }
+
+        }
+    }
+
+    class FileFilterImpl
+        implements FileFilter
+    {
+
+        private final List<String> rejectedFilePaths;
+
+        private final int webAppDirIndex;
+
+        public FileFilterImpl( File webAppDirectory, String[] rejectedFilePaths )
+        {
+            if ( rejectedFilePaths != null )
+            {
+                this.rejectedFilePaths = Arrays.asList( rejectedFilePaths );
+            }
+            else
+            {
+                this.rejectedFilePaths = new ArrayList<>();
+            }
+            this.webAppDirIndex = webAppDirectory.getAbsolutePath().length() + 1;
+        }
+
+        public boolean accept( File file )
+        {
+            String effectiveRelativePath = buildRelativePath( file );
+            return !( rejectedFilePaths.contains( effectiveRelativePath ) || file.isDirectory() );
+        }
+
+        private String buildRelativePath( File f )
+        {
+            return f.getAbsolutePath().substring( webAppDirIndex );
+        }
+    }
+
+}
diff --git a/Java/maven-war-plugin-AbstractWarExplodedMojoTest_104/metadata.json b/Java/maven-war-plugin-AbstractWarExplodedMojoTest_104/metadata.json
new file mode 100644
index 000000000..c9aac8575
--- /dev/null
+++ b/Java/maven-war-plugin-AbstractWarExplodedMojoTest_104/metadata.json
@@ -0,0 +1,21 @@
+{
+  "language": "java",
+  "id": "maven-war-plugin-AbstractWarExplodedMojoTest_104",
+  "buggyPath": ".",
+  "referencePath": null,
+  "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+  "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+  "categories": [
+    "safety",
+    "npe"
+  ],
+  "npe": {
+    "filepath": "src/test/java/org/apache/maven/plugins/war/AbstractWarExplodedMojoTest.java",
+    "line": 110,
+    "npe_method": "setUpMojo",
+    "deref_field": "artifactStubs",
+    "npe_class": "AbstractWarExplodedMojoTest",
+    "repo": "maven-war-plugin",
+    "bug_id": "AbstractWarExplodedMojoTest_104"
+  }
+}
diff --git a/Java/maven-war-plugin-AbstractWarExplodedMojoTest_104/npe.json b/Java/maven-war-plugin-AbstractWarExplodedMojoTest_104/npe.json
new file mode 100644
index 000000000..a413444cb
--- /dev/null
+++ b/Java/maven-war-plugin-AbstractWarExplodedMojoTest_104/npe.json
@@ -0,0 +1,7 @@
+{
+    "filepath": "src/test/java/org/apache/maven/plugins/war/AbstractWarExplodedMojoTest.java",
+    "line": 110,
+    "npe_method": "setUpMojo",
+    "deref_field": "artifactStubs",
+    "npe_class": "AbstractWarExplodedMojoTest"
+}
\ No newline at end of file
diff --git a/Java/maven-war-plugin-AbstractWarExplodedMojoTest_84/Dockerfile b/Java/maven-war-plugin-AbstractWarExplodedMojoTest_84/Dockerfile
new file mode 100644
index 000000000..34955205a
--- /dev/null
+++ b/Java/maven-war-plugin-AbstractWarExplodedMojoTest_84/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:maven-war-plugin
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+    && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+    && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+    && mv /tmp/buggy.java $BUGGY_PATH \
+    && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/maven-war-plugin-AbstractWarExplodedMojoTest_84/buggy.java b/Java/maven-war-plugin-AbstractWarExplodedMojoTest_84/buggy.java
new file mode 100644
index 000000000..12a483f54
--- /dev/null
+++ b/Java/maven-war-plugin-AbstractWarExplodedMojoTest_84/buggy.java
@@ -0,0 +1,302 @@
+package org.apache.maven.plugins.war;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.plugin.testing.stubs.ArtifactStub;
+import org.apache.maven.plugins.war.stub.MavenProjectArtifactsStub;
+import org.codehaus.plexus.util.FileUtils;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * @author Stephane Nicoll
+ */
+public abstract class AbstractWarExplodedMojoTest
+    extends AbstractWarMojoTest
+{
+
+    protected WarExplodedMojo mojo;
+
+    public void setUp()
+        throws Exception
+    {
+        super.setUp();
+        mojo = (WarExplodedMojo) lookupMojo( "exploded", getPomFile() );
+    }
+
+    /**
+     * Returns the pom configuration to use.
+     *
+     * @return the pom configuration
+     */
+    protected abstract File getPomFile();
+
+    /**
+     * Returns the test directory to use.
+     *
+     * @return the test directory
+     */
+    protected abstract File getTestDirectory();
+
+    /**
+     * Configures the exploded mojo for the specified test.
+     * 
+     * If the <tt>sourceFiles</tt> parameter is <tt>null</tt>, sample JSPs are created by default.
+     *
+     * @param testId the id of the test
+     * @param artifactStubs the dependencies (may be null)
+     * @param sourceFiles the source files to create (may be null)
+     * @return the webapp directory
+     * @throws Exception if an error occurs while configuring the mojo
+     */
+/**
+ * Configures the exploded mojo for the specified test.
+ *
+ * If the <tt>sourceFiles</tt> parameter is <tt>null</tt>, sample JSPs are created by default.
+ *
+ * @param testId
+ * 		the id of the test
+ * @param artifactStubs
+ * 		the dependencies (may be null)
+ * @param sourceFiles
+ * 		the source files to create (may be null)
+ * @return the webapp directory
+ * @throws Exception
+ * 		if an error occurs while configuring the mojo
+ */
+protected java.io.File setUpMojo(final java.lang.String testId, org.apache.maven.plugin.testing.stubs.ArtifactStub[] artifactStubs, java.lang.String[] sourceFiles) throws java.lang.Exception {
+    final org.apache.maven.plugins.war.stub.MavenProjectArtifactsStub project = new org.apache.maven.plugins.war.stub.MavenProjectArtifactsStub();
+    final java.io.File webAppDirectory = new java.io.File(getTestDirectory(), testId);
+    // Create the webapp sources
+    java.io.File webAppSource;
+    {
+        webAppSource = createWebAppSource(testId, false);
+        for (java.lang.String sourceFile : /* NPEX_NULL_EXP */
+        sourceFiles) {
+            java.io.File sample = new java.io.File(webAppSource, sourceFile);
+            createFile(sample);
+        }
+    }
+    final java.io.File classesDir = createClassesDir(testId, true);
+    final java.io.File workDirectory = new java.io.File(getTestDirectory(), "/war/work-" + testId);
+    createDir(workDirectory);
+    if (artifactStubs != null) {
+        for (org.apache.maven.plugin.testing.stubs.ArtifactStub artifactStub : artifactStubs) {
+            project.addArtifact(artifactStub);
+        }
+    }
+    configureMojo(mojo, new java.util.LinkedList<java.lang.String>(), classesDir, webAppSource, webAppDirectory, project);
+    setVariableValueToObject(mojo, "workDirectory", workDirectory);
+    return webAppDirectory;
+}
+
+    /**
+     * Configures the exploded mojo for the specified test.
+     *
+     * @param testId the id of the test
+     * @param artifactStubs the dependencies (may be null)
+     * @return the webapp directory
+     * @throws Exception if an error occurs while configuring the mojo
+     */
+    protected File setUpMojo( final String testId, ArtifactStub[] artifactStubs )
+        throws Exception
+    {
+        return setUpMojo( testId, artifactStubs, null );
+    }
+
+    /**
+     * Cleans up a directory.
+     *
+     * @param directory the directory to remove
+     * @throws IOException if an error occurred while removing the directory
+     */
+    protected void cleanDirectory( File directory )
+        throws IOException
+    {
+        if ( directory != null && directory.isDirectory() && directory.exists() )
+        {
+            FileUtils.deleteDirectory( directory );
+        }
+    }
+
+    /**
+     * Asserts the default content of the war based on the specified webapp directory.
+     *
+     * @param webAppDirectory the webapp directory
+     * @return a list of File objects that have been asserted
+     */
+    protected List<File> assertDefaultContent( File webAppDirectory )
+    {
+        // Validate content of the webapp
+        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
+        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );
+
+        assertTrue( "source file not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
+        assertTrue( "source file not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );
+
+        final List<File> content = new ArrayList<>();
+        content.add( expectedWebSourceFile );
+        content.add( expectedWebSource2File );
+
+        return content;
+    }
+
+    /**
+     * Asserts the web.xml file of the war based on the specified webapp directory.
+     *
+     * @param webAppDirectory the webapp directory
+     * @return a list with the web.xml File object
+     */
+    protected List<File> assertWebXml( File webAppDirectory )
+    {
+        File expectedWEBXMLFile = new File( webAppDirectory, "WEB-INF/web.xml" );
+        assertTrue( "web xml not found: " + expectedWEBXMLFile.toString(), expectedWEBXMLFile.exists() );
+
+        final List<File> content = new ArrayList<>();
+        content.add( expectedWEBXMLFile );
+
+        return content;
+    }
+
+    /**
+     * Asserts custom content of the war based on the specified webapp directory.
+     *
+     * @param webAppDirectory the webapp directory
+     * @param filePaths an array of file paths relative to the webapp directory
+     * @param customMessage a custom message if an assertion fails
+     * @return a list of File objects that have been inspected
+     */
+    protected List<File> assertCustomContent( File webAppDirectory, String[] filePaths, String customMessage )
+    {
+        final List<File> content = new ArrayList<>();
+        for ( String filePath : filePaths )
+        {
+            final File expectedFile = new File( webAppDirectory, filePath );
+            if ( customMessage != null )
+            {
+                assertTrue( customMessage + " - " + expectedFile.toString(), expectedFile.exists() );
+            }
+            else
+            {
+                assertTrue( "source file not found: " + expectedFile.toString(), expectedFile.exists() );
+            }
+            content.add( expectedFile );
+        }
+        return content;
+    }
+
+    /**
+     * Asserts that the webapp contains only the specified files.
+     *
+     * @param webAppDirectory the webapp directory
+     * @param expectedFiles the expected files
+     * @param filter an optional filter to ignore some resources
+     */
+    protected void assertWebAppContent( File webAppDirectory, List<File> expectedFiles, FileFilter filter )
+    {
+        final List<File> webAppContent = new ArrayList<>();
+        if ( filter != null )
+        {
+            buildFilesList( webAppDirectory, filter, webAppContent );
+        }
+        else
+        {
+            buildFilesList( webAppDirectory, new FileFilterImpl( webAppDirectory, null ), webAppContent );
+        }
+
+        // Now we have the files, sort them.
+        Collections.sort( expectedFiles );
+        Collections.sort( webAppContent );
+        assertEquals( "Invalid webapp content, expected " + expectedFiles.size() + "file(s) " + expectedFiles
+            + " but got " + webAppContent.size() + " file(s) " + webAppContent, expectedFiles, webAppContent );
+    }
+
+    /**
+     * Builds the list of files and directories from the specified dir.
+     * 
+     * Note that the filter is not used the usual way. If the filter does not accept the current file, it's not added
+     * but yet the subdirectories are added if any.
+     *
+     * @param dir the base directory
+     * @param filter the filter
+     * @param content the current content, updated recursively
+     */
+    private void buildFilesList( final File dir, FileFilter filter, final List<File> content )
+    {
+        final File[] files = dir.listFiles();
+
+        for ( File file : files )
+        {
+            // Add the file if the filter is ok with it
+            if ( filter.accept( file ) )
+            {
+                content.add( file );
+            }
+
+            // Even if the file is not accepted and is a directory, add it
+            if ( file.isDirectory() )
+            {
+                buildFilesList( file, filter, content );
+            }
+
+        }
+    }
+
+    class FileFilterImpl
+        implements FileFilter
+    {
+
+        private final List<String> rejectedFilePaths;
+
+        private final int webAppDirIndex;
+
+        public FileFilterImpl( File webAppDirectory, String[] rejectedFilePaths )
+        {
+            if ( rejectedFilePaths != null )
+            {
+                this.rejectedFilePaths = Arrays.asList( rejectedFilePaths );
+            }
+            else
+            {
+                this.rejectedFilePaths = new ArrayList<>();
+            }
+            this.webAppDirIndex = webAppDirectory.getAbsolutePath().length() + 1;
+        }
+
+        public boolean accept( File file )
+        {
+            String effectiveRelativePath = buildRelativePath( file );
+            return !( rejectedFilePaths.contains( effectiveRelativePath ) || file.isDirectory() );
+        }
+
+        private String buildRelativePath( File f )
+        {
+            return f.getAbsolutePath().substring( webAppDirIndex );
+        }
+    }
+
+}
diff --git a/Java/maven-war-plugin-AbstractWarExplodedMojoTest_84/metadata.json b/Java/maven-war-plugin-AbstractWarExplodedMojoTest_84/metadata.json
new file mode 100644
index 000000000..af40fb8f2
--- /dev/null
+++ b/Java/maven-war-plugin-AbstractWarExplodedMojoTest_84/metadata.json
@@ -0,0 +1,21 @@
+{
+  "language": "java",
+  "id": "maven-war-plugin-AbstractWarExplodedMojoTest_84",
+  "buggyPath": ".",
+  "referencePath": null,
+  "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+  "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+  "categories": [
+    "safety",
+    "npe"
+  ],
+  "npe": {
+    "filepath": "src/test/java/org/apache/maven/plugins/war/AbstractWarExplodedMojoTest.java",
+    "line": 99,
+    "npe_method": "setUpMojo",
+    "deref_field": "sourceFiles",
+    "npe_class": "AbstractWarExplodedMojoTest",
+    "repo": "maven-war-plugin",
+    "bug_id": "AbstractWarExplodedMojoTest_84"
+  }
+}
diff --git a/Java/maven-war-plugin-AbstractWarExplodedMojoTest_84/npe.json b/Java/maven-war-plugin-AbstractWarExplodedMojoTest_84/npe.json
new file mode 100644
index 000000000..f1b3686da
--- /dev/null
+++ b/Java/maven-war-plugin-AbstractWarExplodedMojoTest_84/npe.json
@@ -0,0 +1,7 @@
+{
+    "filepath": "src/test/java/org/apache/maven/plugins/war/AbstractWarExplodedMojoTest.java",
+    "line": 99,
+    "npe_method": "setUpMojo",
+    "deref_field": "sourceFiles",
+    "npe_class": "AbstractWarExplodedMojoTest"
+}
\ No newline at end of file
diff --git a/Java/maven-war-plugin-AbstractWarPackagingTask_99/Dockerfile b/Java/maven-war-plugin-AbstractWarPackagingTask_99/Dockerfile
new file mode 100644
index 000000000..34955205a
--- /dev/null
+++ b/Java/maven-war-plugin-AbstractWarPackagingTask_99/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:maven-war-plugin
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+    && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+    && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+    && mv /tmp/buggy.java $BUGGY_PATH \
+    && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/maven-war-plugin-AbstractWarPackagingTask_99/buggy.java b/Java/maven-war-plugin-AbstractWarPackagingTask_99/buggy.java
new file mode 100644
index 000000000..b1d0f3bab
--- /dev/null
+++ b/Java/maven-war-plugin-AbstractWarPackagingTask_99/buggy.java
@@ -0,0 +1,506 @@
+package org.apache.maven.plugins.war.packaging;
+
+/*
+ * 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.
+ */
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.commons.io.input.XmlStreamReader;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugins.war.util.PathSet;
+import org.apache.maven.plugins.war.util.WebappStructure;
+import org.apache.maven.shared.filtering.MavenFilteringException;
+import org.apache.maven.shared.mapping.MappingUtils;
+import org.codehaus.plexus.archiver.ArchiverException;
+import org.codehaus.plexus.archiver.UnArchiver;
+import org.codehaus.plexus.archiver.jar.JarArchiver;
+import org.codehaus.plexus.archiver.manager.NoSuchArchiverException;
+import org.codehaus.plexus.interpolation.InterpolationException;
+import org.codehaus.plexus.util.DirectoryScanner;
+import org.codehaus.plexus.util.FileUtils;
+
+/**
+ * @author Stephane Nicoll
+ */
+public abstract class AbstractWarPackagingTask
+    implements WarPackagingTask
+{
+    /**
+     * The default list of includes.
+     */
+    public static final String[] DEFAULT_INCLUDES = { "**/**" };
+
+    /**
+     * The {@code WEB-INF} path.
+     */
+    public static final String WEB_INF_PATH = "WEB-INF";
+
+    /**
+     * The {@code META-INF} path.
+     */
+    public static final String META_INF_PATH = "META-INF";
+
+    /**
+     * The {@code classes} path.
+     */
+    public static final String CLASSES_PATH = "WEB-INF/classes/";
+
+    /**
+     * The {@code lib} path.
+     */
+    public static final String LIB_PATH = "WEB-INF/lib/";
+
+    /**
+     * Copies the files if possible with an optional target prefix.
+     * 
+     * Copy uses a first-win strategy: files that have already been copied by previous tasks are ignored. This method
+     * makes sure to update the list of protected files which gives the list of files that have already been copied.
+     * 
+     * If the structure of the source directory is not the same as the root of the webapp, use the <tt>targetPrefix</tt>
+     * parameter to specify in which particular directory the files should be copied. Use <tt>null</tt> to copy the
+     * files with the same structure
+     *
+     * @param sourceId the source id
+     * @param context the context to use
+     * @param sourceBaseDir the base directory from which the <tt>sourceFilesSet</tt> will be copied
+     * @param sourceFilesSet the files to be copied
+     * @param targetPrefix the prefix to add to the target file name
+     * @param filtered filter or not.
+     * @throws IOException if an error occurred while copying the files
+     * @throws MojoExecutionException if an error occurs.
+     */
+/**
+ * Copies the files if possible with an optional target prefix.
+ *
+ * Copy uses a first-win strategy: files that have already been copied by previous tasks are ignored. This method
+ * makes sure to update the list of protected files which gives the list of files that have already been copied.
+ *
+ * If the structure of the source directory is not the same as the root of the webapp, use the <tt>targetPrefix</tt>
+ * parameter to specify in which particular directory the files should be copied. Use <tt>null</tt> to copy the
+ * files with the same structure
+ *
+ * @param sourceId
+ * 		the source id
+ * @param context
+ * 		the context to use
+ * @param sourceBaseDir
+ * 		the base directory from which the <tt>sourceFilesSet</tt> will be copied
+ * @param sourceFilesSet
+ * 		the files to be copied
+ * @param targetPrefix
+ * 		the prefix to add to the target file name
+ * @param filtered
+ * 		filter or not.
+ * @throws IOException
+ * 		if an error occurred while copying the files
+ * @throws MojoExecutionException
+ * 		if an error occurs.
+ */
+protected void copyFiles(java.lang.String sourceId, org.apache.maven.plugins.war.packaging.WarPackagingContext context, java.io.File sourceBaseDir, org.apache.maven.plugins.war.util.PathSet sourceFilesSet, java.lang.String targetPrefix, boolean filtered) throws java.io.IOException, org.apache.maven.plugin.MojoExecutionException {
+    for (java.lang.String fileToCopyName : sourceFilesSet.paths()) {
+        final java.io.File sourceFile = new java.io.File(sourceBaseDir, fileToCopyName);
+        java.lang.String destinationFileName;
+        {
+            destinationFileName = /* NPEX_NULL_EXP */
+            targetPrefix + fileToCopyName;
+        }
+        if (filtered && (!context.isNonFilteredExtension(sourceFile.getName()))) {
+            copyFilteredFile(sourceId, context, sourceFile, destinationFileName);
+        } else {
+            copyFile(sourceId, context, sourceFile, destinationFileName);
+        }
+    }
+}
+
+    /**
+     * Copies the files if possible as is.
+     * 
+     * Copy uses a first-win strategy: files that have already been copied by previous tasks are ignored. This method
+     * makes sure to update the list of protected files which gives the list of files that have already been copied.
+     *
+     * @param sourceId the source id
+     * @param context the context to use
+     * @param sourceBaseDir the base directory from which the <tt>sourceFilesSet</tt> will be copied
+     * @param sourceFilesSet the files to be copied
+     * @param filtered filter or not.
+     * @throws IOException if an error occurred while copying the files
+     * @throws MojoExecutionException break the build.
+     */
+    protected void copyFiles( String sourceId, WarPackagingContext context, File sourceBaseDir, PathSet sourceFilesSet,
+                              boolean filtered )
+        throws IOException, MojoExecutionException
+    {
+        copyFiles( sourceId, context, sourceBaseDir, sourceFilesSet, null, filtered );
+    }
+
+    /**
+     * Copy the specified file if the target location has not yet already been used.
+     * 
+     * The <tt>targetFileName</tt> is the relative path according to the root of the generated web application.
+     *
+     * @param sourceId the source id
+     * @param context the context to use
+     * @param file the file to copy
+     * @param targetFilename the relative path according to the root of the webapp
+     * @throws IOException if an error occurred while copying
+     */
+    // CHECKSTYLE_OFF: LineLength
+    protected void copyFile( String sourceId, final WarPackagingContext context, final File file, String targetFilename )
+        throws IOException
+    // CHECKSTYLE_ON: LineLength
+    {
+        final File targetFile = new File( context.getWebappDirectory(), targetFilename );
+
+        if ( file.isFile() )
+        {
+            context.getWebappStructure().registerFile( sourceId, targetFilename,
+           new WebappStructure.RegistrationCallback()
+           {
+               public void registered( String ownerId, String targetFilename )
+                   throws IOException
+               {
+                   copyFile( context, file, targetFile, targetFilename,
+                             false );
+               }
+    
+               public void alreadyRegistered( String ownerId,
+                                              String targetFilename )
+                   throws IOException
+               {
+                   copyFile( context, file, targetFile, targetFilename,
+                             true );
+               }
+    
+               public void refused( String ownerId, String targetFilename,
+                                    String actualOwnerId )
+                   throws IOException
+               {
+                   context.getLog().debug( " - "
+                                               + targetFilename
+                                               + " wasn't copied because it has "
+                                               + "already been packaged for overlay ["
+                                               + actualOwnerId + "]." );
+               }
+    
+               public void superseded( String ownerId,
+                                       String targetFilename,
+                                       String deprecatedOwnerId )
+                   throws IOException
+               {
+                   context.getLog().info( "File ["
+                                              + targetFilename
+                                              + "] belonged to overlay ["
+                                              + deprecatedOwnerId
+                                              + "] so it will be overwritten." );
+                   copyFile( context, file, targetFile, targetFilename,
+                             false );
+               }
+    
+               public void supersededUnknownOwner( String ownerId,
+                                                   String targetFilename,
+                                                   String unknownOwnerId )
+                   throws IOException
+               {
+                   // CHECKSTYLE_OFF: LineLength
+                   context.getLog().warn( "File ["
+                                              + targetFilename
+                                              + "] belonged to overlay ["
+                                              + unknownOwnerId
+                                              + "] which does not exist anymore in the current project. It is recommended to invoke "
+                                              + "clean if the dependencies of the project changed." );
+                   // CHECKSTYLE_ON: LineLength
+                   copyFile( context, file, targetFile, targetFilename,
+                             false );
+               }
+           } );
+        }
+        else if ( !targetFile.exists() && !targetFile.mkdirs() )
+        {
+            context.getLog().info( "Failed to create directory " + targetFile.getAbsolutePath() );
+        }
+    }
+
+    /**
+     * Copy the specified file if the target location has not yet already been used and filter its content with the
+     * configured filter properties.
+     * 
+     * The <tt>targetFileName</tt> is the relative path according to the root of the generated web application.
+     *
+     * @param sourceId the source id
+     * @param context the context to use
+     * @param file the file to copy
+     * @param targetFilename the relative path according to the root of the webapp
+     * @return true if the file has been copied, false otherwise
+     * @throws IOException if an error occurred while copying
+     * @throws MojoExecutionException if an error occurred while retrieving the filter properties
+     */
+    protected boolean copyFilteredFile( String sourceId, final WarPackagingContext context, File file,
+                                        String targetFilename )
+        throws IOException, MojoExecutionException
+    {
+        context.addResource( targetFilename );
+
+        if ( context.getWebappStructure().registerFile( sourceId, targetFilename ) )
+        {
+            final File targetFile = new File( context.getWebappDirectory(), targetFilename );
+            final String encoding;
+            try
+            {
+                if ( isXmlFile( file ) )
+                {
+                    // For xml-files we extract the encoding from the files
+                    encoding = getEncoding( file );
+                }
+                else
+                {
+                    // For all others we use the configured encoding
+                    encoding = context.getResourceEncoding();
+                }
+                // fix for MWAR-36, ensures that the parent dir are created first
+                targetFile.getParentFile().mkdirs();
+
+                context.getMavenFileFilter().copyFile( file, targetFile, true, context.getFilterWrappers(), encoding );
+            }
+            catch ( MavenFilteringException e )
+            {
+                throw new MojoExecutionException( e.getMessage(), e );
+            }
+            // CHECKSTYLE_OFF: LineLength
+            // Add the file to the protected list
+            context.getLog().debug( " + " + targetFilename + " has been copied (filtered encoding='" + encoding + "')." );
+            // CHECKSTYLE_ON: LineLength
+            return true;
+        }
+        else
+        {
+            context.getLog().debug( " - " + targetFilename
+                                        + " wasn't copied because it has already been packaged (filtered)." );
+            return false;
+        }
+    }
+
+    /**
+     * Unpacks the specified file to the specified directory.
+     *
+     * @param context the packaging context
+     * @param file the file to unpack
+     * @param unpackDirectory the directory to use for th unpacked file
+     * @throws MojoExecutionException if an error occurred while unpacking the file
+     */
+    protected void doUnpack( WarPackagingContext context, File file, File unpackDirectory )
+        throws MojoExecutionException
+    {
+        String archiveExt = FileUtils.getExtension( file.getAbsolutePath() ).toLowerCase();
+
+        try
+        {
+            UnArchiver unArchiver = context.getArchiverManager().getUnArchiver( archiveExt );
+            unArchiver.setSourceFile( file );
+            unArchiver.setDestDirectory( unpackDirectory );
+            unArchiver.setOverwrite( true );
+            unArchiver.extract();
+        }
+        catch ( ArchiverException e )
+        {
+            throw new MojoExecutionException( "Error unpacking file [" + file.getAbsolutePath() + "]" + " to ["
+                + unpackDirectory.getAbsolutePath() + "]", e );
+        }
+        catch ( NoSuchArchiverException e )
+        {
+            context.getLog().warn( "Skip unpacking dependency file [" + file.getAbsolutePath()
+                                       + " with unknown extension [" + archiveExt + "]" );
+        }
+    }
+
+    /**
+     * Copy file from source to destination. The directories up to <code>destination</code> will be created if they
+     * don't already exist. if the <code>onlyIfModified</code> flag is <tt>false</tt>, <code>destination</code> will be
+     * overwritten if it already exists. If the flag is <tt>true</tt> destination will be overwritten if it's not up to
+     * date.
+     *
+     * @param context the packaging context
+     * @param source an existing non-directory <code>File</code> to copy bytes from
+     * @param destination a non-directory <code>File</code> to write bytes to (possibly overwriting).
+     * @param targetFilename the relative path of the file from the webapp root directory
+     * @param onlyIfModified if true, copy the file only if the source has changed, always copy otherwise
+     * @return true if the file has been copied/updated, false otherwise
+     * @throws IOException if <code>source</code> does not exist, <code>destination</code> cannot be written to, or an
+     *             IO error occurs during copying
+     */
+    protected boolean copyFile( WarPackagingContext context, File source, File destination, String targetFilename,
+                                boolean onlyIfModified )
+        throws IOException
+    {
+        context.addResource( targetFilename );
+
+        if ( onlyIfModified && destination.lastModified() >= source.lastModified() )
+        {
+            context.getLog().debug( " * " + targetFilename + " is up to date." );
+            return false;
+        }
+        else
+        {
+            if ( source.isDirectory() )
+            {
+                context.getLog().warn( " + " + targetFilename + " is packaged from the source folder" );
+
+                try
+                {
+                    JarArchiver archiver = context.getJarArchiver();
+                    archiver.addDirectory( source );
+                    archiver.setDestFile( destination );
+                    archiver.createArchive();
+                }
+                catch ( ArchiverException e )
+                {
+                    String msg = "Failed to create " + targetFilename;
+                    context.getLog().error( msg, e );
+                    IOException ioe = new IOException( msg );
+                    ioe.initCause( e );
+                    throw ioe;
+                }
+            }
+            else
+            {
+                FileUtils.copyFile( source.getCanonicalFile(), destination );
+                // preserve timestamp
+                destination.setLastModified( source.lastModified() );
+                context.getLog().debug( " + " + targetFilename + " has been copied." );
+            }
+            return true;
+        }
+    }
+
+    /**
+     * Get the encoding from an XML-file.
+     *
+     * @param webXml the XML-file
+     * @return The encoding of the XML-file, or UTF-8 if it's not specified in the file
+     * @throws java.io.IOException if an error occurred while reading the file
+     */
+    protected String getEncoding( File webXml )
+        throws IOException
+    {
+        try ( XmlStreamReader xmlReader = new XmlStreamReader( webXml ) )
+        {
+            return xmlReader.getEncoding();
+        }
+    }
+
+    /**
+     * Returns the file to copy. If the includes are <tt>null</tt> or empty, the default includes are used.
+     *
+     * @param baseDir the base directory to start from
+     * @param includes the includes
+     * @param excludes the excludes
+     * @return the files to copy
+     */
+    protected PathSet getFilesToIncludes( File baseDir, String[] includes, String[] excludes )
+    {
+        return getFilesToIncludes( baseDir, includes, excludes, false );
+    }
+
+    /**
+     * Returns the file to copy. If the includes are <tt>null</tt> or empty, the default includes are used.
+     *
+     * @param baseDir the base directory to start from
+     * @param includes the includes
+     * @param excludes the excludes
+     * @param includeDirectories include directories yes or not.
+     * @return the files to copy
+     */
+    // CHECKSTYLE_OFF: LineLength
+    protected PathSet getFilesToIncludes( File baseDir, String[] includes, String[] excludes, boolean includeDirectories )
+    // CHECKSTYLE_ON: LineLength
+    {
+        final DirectoryScanner scanner = new DirectoryScanner();
+        scanner.setBasedir( baseDir );
+
+        if ( excludes != null )
+        {
+            scanner.setExcludes( excludes );
+        }
+        scanner.addDefaultExcludes();
+
+        if ( includes != null && includes.length > 0 )
+        {
+            scanner.setIncludes( includes );
+        }
+        else
+        {
+            scanner.setIncludes( DEFAULT_INCLUDES );
+        }
+
+        scanner.scan();
+
+        PathSet pathSet = new PathSet( scanner.getIncludedFiles() );
+
+        if ( includeDirectories )
+        {
+            pathSet.addAll( scanner.getIncludedDirectories() );
+        }
+
+        return pathSet;
+    }
+
+    /**
+     * Returns the final name of the specified artifact.
+     * 
+     * If the <tt>outputFileNameMapping</tt> is set, it is used, otherwise the standard naming scheme is used.
+     *
+     * @param context the packaging context
+     * @param artifact the artifact
+     * @return the converted filename of the artifact
+     * @throws InterpolationException in case of interpolation problem.
+     */
+    protected String getArtifactFinalName( WarPackagingContext context, Artifact artifact )
+        throws InterpolationException
+    {
+        if ( context.getOutputFileNameMapping() != null )
+        {
+            return MappingUtils.evaluateFileNameMapping( context.getOutputFileNameMapping(), artifact );
+        }
+
+        String classifier = artifact.getClassifier();
+        if ( ( classifier != null ) && !( "".equals( classifier.trim() ) ) )
+        {
+            return MappingUtils.evaluateFileNameMapping( MappingUtils.DEFAULT_FILE_NAME_MAPPING_CLASSIFIER, artifact );
+        }
+        else
+        {
+            return MappingUtils.evaluateFileNameMapping( MappingUtils.DEFAULT_FILE_NAME_MAPPING, artifact );
+        }
+
+    }
+
+    /**
+     * Returns <code>true</code> if the <code>File</code>-object is a file (not a directory) that is not
+     * <code>null</code> and has a file name that ends in ".xml".
+     *
+     * @param file The file to check
+     * @return <code>true</code> if the file is an xml-file, otherwise <code>false</code>
+     * @since 2.3
+     */
+    private boolean isXmlFile( File file )
+    {
+        return file != null && file.isFile() && file.getName().endsWith( ".xml" );
+    }
+}
diff --git a/Java/maven-war-plugin-AbstractWarPackagingTask_99/metadata.json b/Java/maven-war-plugin-AbstractWarPackagingTask_99/metadata.json
new file mode 100644
index 000000000..57f0b37ab
--- /dev/null
+++ b/Java/maven-war-plugin-AbstractWarPackagingTask_99/metadata.json
@@ -0,0 +1,21 @@
+{
+  "language": "java",
+  "id": "maven-war-plugin-AbstractWarPackagingTask_99",
+  "buggyPath": ".",
+  "referencePath": null,
+  "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+  "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+  "categories": [
+    "safety",
+    "npe"
+  ],
+  "npe": {
+    "filepath": "src/main/java/org/apache/maven/plugins/war/packaging/AbstractWarPackagingTask.java",
+    "line": 123,
+    "npe_method": "copyFiles",
+    "deref_field": "targetPrefix",
+    "npe_class": "AbstractWarPackagingTask",
+    "repo": "maven-war-plugin",
+    "bug_id": "AbstractWarPackagingTask_99"
+  }
+}
diff --git a/Java/maven-war-plugin-AbstractWarPackagingTask_99/npe.json b/Java/maven-war-plugin-AbstractWarPackagingTask_99/npe.json
new file mode 100644
index 000000000..cdcca5246
--- /dev/null
+++ b/Java/maven-war-plugin-AbstractWarPackagingTask_99/npe.json
@@ -0,0 +1,7 @@
+{
+    "filepath": "src/main/java/org/apache/maven/plugins/war/packaging/AbstractWarPackagingTask.java",
+    "line": 123,
+    "npe_method": "copyFiles",
+    "deref_field": "targetPrefix",
+    "npe_class": "AbstractWarPackagingTask"
+}
\ No newline at end of file
diff --git a/Java/maven-war-plugin-CopyUserManifestTask_59/Dockerfile b/Java/maven-war-plugin-CopyUserManifestTask_59/Dockerfile
new file mode 100644
index 000000000..34955205a
--- /dev/null
+++ b/Java/maven-war-plugin-CopyUserManifestTask_59/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:maven-war-plugin
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+    && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+    && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+    && mv /tmp/buggy.java $BUGGY_PATH \
+    && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/maven-war-plugin-CopyUserManifestTask_59/buggy.java b/Java/maven-war-plugin-CopyUserManifestTask_59/buggy.java
new file mode 100644
index 000000000..35832211c
--- /dev/null
+++ b/Java/maven-war-plugin-CopyUserManifestTask_59/buggy.java
@@ -0,0 +1,69 @@
+package org.apache.maven.plugins.war.packaging;
+
+/*
+ * 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.
+ */
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugin.logging.Log;
+import org.apache.maven.plugin.logging.SystemStreamLog;
+
+/**
+ * @author Haikal Saadh
+ *
+ */
+public class CopyUserManifestTask
+    extends AbstractWarPackagingTask
+{
+
+    /** Instance logger */
+    private Log log;
+
+    public Log getLog()
+    {
+        if ( log == null )
+        {
+            log = new SystemStreamLog();
+        }
+        return log;
+    }
+
+    public void setLog( Log log )
+    {
+        this.log = log;
+    }
+
+public void performPackaging(org.apache.maven.plugins.war.packaging.WarPackagingContext context) throws org.apache.maven.plugin.MojoExecutionException, org.apache.maven.plugin.MojoFailureException {
+    java.io.File userManifest = context.getArchive().getManifestFile();
+    {
+        try {
+            getLog().info("Copying manifest...");
+            java.io.File metainfDir = new java.io.File(context.getWebappDirectory(), org.apache.maven.plugins.war.packaging.AbstractWarPackagingTask.META_INF_PATH);
+            copyFile(context, /* NPEX_NULL_EXP */
+            userManifest, new java.io.File(metainfDir, "MANIFEST.MF"), "META-INF/MANIFEST.MF", true);
+        } catch (java.io.IOException e) {
+            throw new org.apache.maven.plugin.MojoExecutionException("Error copying user manifest", e);
+        }
+    }
+}
+
+}
diff --git a/Java/maven-war-plugin-CopyUserManifestTask_59/metadata.json b/Java/maven-war-plugin-CopyUserManifestTask_59/metadata.json
new file mode 100644
index 000000000..76d37b651
--- /dev/null
+++ b/Java/maven-war-plugin-CopyUserManifestTask_59/metadata.json
@@ -0,0 +1,21 @@
+{
+  "language": "java",
+  "id": "maven-war-plugin-CopyUserManifestTask_59",
+  "buggyPath": ".",
+  "referencePath": null,
+  "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+  "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+  "categories": [
+    "safety",
+    "npe"
+  ],
+  "npe": {
+    "filepath": "src/main/java/org/apache/maven/plugins/war/packaging/CopyUserManifestTask.java",
+    "line": 62,
+    "npe_method": "performPackaging",
+    "deref_field": "userManifest",
+    "npe_class": "CopyUserManifestTask",
+    "repo": "maven-war-plugin",
+    "bug_id": "CopyUserManifestTask_59"
+  }
+}
diff --git a/Java/maven-war-plugin-CopyUserManifestTask_59/npe.json b/Java/maven-war-plugin-CopyUserManifestTask_59/npe.json
new file mode 100644
index 000000000..644004bce
--- /dev/null
+++ b/Java/maven-war-plugin-CopyUserManifestTask_59/npe.json
@@ -0,0 +1,7 @@
+{
+    "filepath": "src/main/java/org/apache/maven/plugins/war/packaging/CopyUserManifestTask.java",
+    "line": 62,
+    "npe_method": "performPackaging",
+    "deref_field": "userManifest",
+    "npe_class": "CopyUserManifestTask"
+}
\ No newline at end of file
diff --git a/Java/maven-war-plugin-JarArtifactStub_135/Dockerfile b/Java/maven-war-plugin-JarArtifactStub_135/Dockerfile
new file mode 100644
index 000000000..34955205a
--- /dev/null
+++ b/Java/maven-war-plugin-JarArtifactStub_135/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:maven-war-plugin
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+    && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+    && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+    && mv /tmp/buggy.java $BUGGY_PATH \
+    && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/maven-war-plugin-JarArtifactStub_135/buggy.java b/Java/maven-war-plugin-JarArtifactStub_135/buggy.java
new file mode 100644
index 000000000..399bb7196
--- /dev/null
+++ b/Java/maven-war-plugin-JarArtifactStub_135/buggy.java
@@ -0,0 +1,149 @@
+package org.apache.maven.plugins.war.stub;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.artifact.handler.ArtifactHandler;
+
+import java.io.File;
+
+public class JarArtifactStub
+    extends AbstractArtifactStub
+{
+
+    protected String groupId;
+
+    protected String artifactId;
+
+    protected String version;
+
+    protected boolean optional = false;
+
+    protected String scope;
+
+    private File file;
+
+    private ArtifactHandler artifactHandler;
+
+    public JarArtifactStub( String basedir, ArtifactHandler artifactHandler )
+    {
+        super( basedir );
+        this.artifactHandler = artifactHandler;
+    }
+
+    public void setGroupId( String id )
+    {
+        groupId = id;
+    }
+
+    public String getGroupId()
+    {
+        if ( groupId != null )
+        {
+            return groupId;
+        }
+        else
+        {
+            return "org.sample.jar";
+        }
+    }
+
+    public String getType()
+    {
+        return "jar";
+    }
+
+    public void setArtifactId( String artifactId )
+    {
+        this.artifactId = artifactId;
+    }
+
+    public String getArtifactId()
+    {
+        if ( artifactId != null )
+        {
+            return artifactId;
+        }
+        else
+        {
+            return "jarartifact";
+        }
+    }
+
+    public String getVersion()
+    {
+        if ( version != null )
+        {
+            return version;
+        }
+        else
+        {
+            return super.getVersion();
+        }
+    }
+
+    public void setVersion( String version )
+    {
+        this.version = version;
+    }
+
+    public boolean isOptional()
+    {
+        return optional;
+    }
+
+    public void setOptional( boolean optional )
+    {
+        this.optional = optional;
+    }
+
+    public String getScope()
+    {
+        if ( scope != null )
+        {
+            return scope;
+        }
+        else
+        {
+            return super.getScope();
+        }
+    }
+
+    public void setScope( String scope )
+    {
+        this.scope = scope;
+    }
+
+public java.io.File getFile() {
+    {
+        return /* NPEX_NULL_EXP */
+        file;
+    }
+}
+
+    public void setFile( File file )
+    {
+        this.file = file;
+    }
+
+    public ArtifactHandler getArtifactHandler()
+    {
+        return artifactHandler;
+    }
+}
diff --git a/Java/maven-war-plugin-JarArtifactStub_135/metadata.json b/Java/maven-war-plugin-JarArtifactStub_135/metadata.json
new file mode 100644
index 000000000..de8c9059c
--- /dev/null
+++ b/Java/maven-war-plugin-JarArtifactStub_135/metadata.json
@@ -0,0 +1,21 @@
+{
+  "language": "java",
+  "id": "maven-war-plugin-JarArtifactStub_135",
+  "buggyPath": ".",
+  "referencePath": null,
+  "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+  "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+  "categories": [
+    "safety",
+    "npe"
+  ],
+  "npe": {
+    "filepath": "src/test/java/org/apache/maven/plugins/war/stub/JarArtifactStub.java",
+    "line": 136,
+    "npe_method": "getFile",
+    "deref_field": "file",
+    "npe_class": "JarArtifactStub",
+    "repo": "maven-war-plugin",
+    "bug_id": "JarArtifactStub_135"
+  }
+}
diff --git a/Java/maven-war-plugin-JarArtifactStub_135/npe.json b/Java/maven-war-plugin-JarArtifactStub_135/npe.json
new file mode 100644
index 000000000..39921ad3a
--- /dev/null
+++ b/Java/maven-war-plugin-JarArtifactStub_135/npe.json
@@ -0,0 +1,7 @@
+{
+    "filepath": "src/test/java/org/apache/maven/plugins/war/stub/JarArtifactStub.java",
+    "line": 136,
+    "npe_method": "getFile",
+    "deref_field": "file",
+    "npe_class": "JarArtifactStub"
+}
\ No newline at end of file
diff --git a/Java/maven-war-plugin-JarArtifactStub_79/Dockerfile b/Java/maven-war-plugin-JarArtifactStub_79/Dockerfile
new file mode 100644
index 000000000..34955205a
--- /dev/null
+++ b/Java/maven-war-plugin-JarArtifactStub_79/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:maven-war-plugin
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+    && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+    && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+    && mv /tmp/buggy.java $BUGGY_PATH \
+    && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/maven-war-plugin-JarArtifactStub_79/buggy.java b/Java/maven-war-plugin-JarArtifactStub_79/buggy.java
new file mode 100644
index 000000000..4b4301a60
--- /dev/null
+++ b/Java/maven-war-plugin-JarArtifactStub_79/buggy.java
@@ -0,0 +1,146 @@
+package org.apache.maven.plugins.war.stub;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.artifact.handler.ArtifactHandler;
+
+import java.io.File;
+
+public class JarArtifactStub
+    extends AbstractArtifactStub
+{
+
+    protected String groupId;
+
+    protected String artifactId;
+
+    protected String version;
+
+    protected boolean optional = false;
+
+    protected String scope;
+
+    private File file;
+
+    private ArtifactHandler artifactHandler;
+
+    public JarArtifactStub( String basedir, ArtifactHandler artifactHandler )
+    {
+        super( basedir );
+        this.artifactHandler = artifactHandler;
+    }
+
+    public void setGroupId( String id )
+    {
+        groupId = id;
+    }
+
+    public String getGroupId()
+    {
+        if ( groupId != null )
+        {
+            return groupId;
+        }
+        else
+        {
+            return "org.sample.jar";
+        }
+    }
+
+    public String getType()
+    {
+        return "jar";
+    }
+
+    public void setArtifactId( String artifactId )
+    {
+        this.artifactId = artifactId;
+    }
+
+public java.lang.String getArtifactId() {
+    {
+        return /* NPEX_NULL_EXP */
+        artifactId;
+    }
+}
+
+    public String getVersion()
+    {
+        if ( version != null )
+        {
+            return version;
+        }
+        else
+        {
+            return super.getVersion();
+        }
+    }
+
+    public void setVersion( String version )
+    {
+        this.version = version;
+    }
+
+    public boolean isOptional()
+    {
+        return optional;
+    }
+
+    public void setOptional( boolean optional )
+    {
+        this.optional = optional;
+    }
+
+    public String getScope()
+    {
+        if ( scope != null )
+        {
+            return scope;
+        }
+        else
+        {
+            return super.getScope();
+        }
+    }
+
+    public void setScope( String scope )
+    {
+        this.scope = scope;
+    }
+
+    public File getFile()
+    {
+        if ( file == null )
+        {
+            return new File( basedir, "/target/test-classes/unit/sample_wars/simple.jar" );
+        }
+        return file;
+    }
+
+    public void setFile( File file )
+    {
+        this.file = file;
+    }
+
+    public ArtifactHandler getArtifactHandler()
+    {
+        return artifactHandler;
+    }
+}
diff --git a/Java/maven-war-plugin-JarArtifactStub_79/metadata.json b/Java/maven-war-plugin-JarArtifactStub_79/metadata.json
new file mode 100644
index 000000000..6d554e08a
--- /dev/null
+++ b/Java/maven-war-plugin-JarArtifactStub_79/metadata.json
@@ -0,0 +1,21 @@
+{
+  "language": "java",
+  "id": "maven-war-plugin-JarArtifactStub_79",
+  "buggyPath": ".",
+  "referencePath": null,
+  "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+  "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+  "categories": [
+    "safety",
+    "npe"
+  ],
+  "npe": {
+    "filepath": "src/test/java/org/apache/maven/plugins/war/stub/JarArtifactStub.java",
+    "line": 80,
+    "npe_method": "getArtifactId",
+    "deref_field": "artifactId",
+    "npe_class": "JarArtifactStub",
+    "repo": "maven-war-plugin",
+    "bug_id": "JarArtifactStub_79"
+  }
+}
diff --git a/Java/maven-war-plugin-JarArtifactStub_79/npe.json b/Java/maven-war-plugin-JarArtifactStub_79/npe.json
new file mode 100644
index 000000000..3506296b7
--- /dev/null
+++ b/Java/maven-war-plugin-JarArtifactStub_79/npe.json
@@ -0,0 +1,7 @@
+{
+    "filepath": "src/test/java/org/apache/maven/plugins/war/stub/JarArtifactStub.java",
+    "line": 80,
+    "npe_method": "getArtifactId",
+    "deref_field": "artifactId",
+    "npe_class": "JarArtifactStub"
+}
\ No newline at end of file
diff --git a/Java/maven-war-plugin-JarArtifactStub_91/Dockerfile b/Java/maven-war-plugin-JarArtifactStub_91/Dockerfile
new file mode 100644
index 000000000..34955205a
--- /dev/null
+++ b/Java/maven-war-plugin-JarArtifactStub_91/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:maven-war-plugin
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+    && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+    && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+    && mv /tmp/buggy.java $BUGGY_PATH \
+    && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/maven-war-plugin-JarArtifactStub_91/buggy.java b/Java/maven-war-plugin-JarArtifactStub_91/buggy.java
new file mode 100644
index 000000000..31d296673
--- /dev/null
+++ b/Java/maven-war-plugin-JarArtifactStub_91/buggy.java
@@ -0,0 +1,146 @@
+package org.apache.maven.plugins.war.stub;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.artifact.handler.ArtifactHandler;
+
+import java.io.File;
+
+public class JarArtifactStub
+    extends AbstractArtifactStub
+{
+
+    protected String groupId;
+
+    protected String artifactId;
+
+    protected String version;
+
+    protected boolean optional = false;
+
+    protected String scope;
+
+    private File file;
+
+    private ArtifactHandler artifactHandler;
+
+    public JarArtifactStub( String basedir, ArtifactHandler artifactHandler )
+    {
+        super( basedir );
+        this.artifactHandler = artifactHandler;
+    }
+
+    public void setGroupId( String id )
+    {
+        groupId = id;
+    }
+
+    public String getGroupId()
+    {
+        if ( groupId != null )
+        {
+            return groupId;
+        }
+        else
+        {
+            return "org.sample.jar";
+        }
+    }
+
+    public String getType()
+    {
+        return "jar";
+    }
+
+    public void setArtifactId( String artifactId )
+    {
+        this.artifactId = artifactId;
+    }
+
+    public String getArtifactId()
+    {
+        if ( artifactId != null )
+        {
+            return artifactId;
+        }
+        else
+        {
+            return "jarartifact";
+        }
+    }
+
+public java.lang.String getVersion() {
+    {
+        return /* NPEX_NULL_EXP */
+        version;
+    }
+}
+
+    public void setVersion( String version )
+    {
+        this.version = version;
+    }
+
+    public boolean isOptional()
+    {
+        return optional;
+    }
+
+    public void setOptional( boolean optional )
+    {
+        this.optional = optional;
+    }
+
+    public String getScope()
+    {
+        if ( scope != null )
+        {
+            return scope;
+        }
+        else
+        {
+            return super.getScope();
+        }
+    }
+
+    public void setScope( String scope )
+    {
+        this.scope = scope;
+    }
+
+    public File getFile()
+    {
+        if ( file == null )
+        {
+            return new File( basedir, "/target/test-classes/unit/sample_wars/simple.jar" );
+        }
+        return file;
+    }
+
+    public void setFile( File file )
+    {
+        this.file = file;
+    }
+
+    public ArtifactHandler getArtifactHandler()
+    {
+        return artifactHandler;
+    }
+}
diff --git a/Java/maven-war-plugin-JarArtifactStub_91/metadata.json b/Java/maven-war-plugin-JarArtifactStub_91/metadata.json
new file mode 100644
index 000000000..6ad7f1048
--- /dev/null
+++ b/Java/maven-war-plugin-JarArtifactStub_91/metadata.json
@@ -0,0 +1,21 @@
+{
+  "language": "java",
+  "id": "maven-war-plugin-JarArtifactStub_91",
+  "buggyPath": ".",
+  "referencePath": null,
+  "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+  "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+  "categories": [
+    "safety",
+    "npe"
+  ],
+  "npe": {
+    "filepath": "src/test/java/org/apache/maven/plugins/war/stub/JarArtifactStub.java",
+    "line": 92,
+    "npe_method": "getVersion",
+    "deref_field": "version",
+    "npe_class": "JarArtifactStub",
+    "repo": "maven-war-plugin",
+    "bug_id": "JarArtifactStub_91"
+  }
+}
diff --git a/Java/maven-war-plugin-JarArtifactStub_91/npe.json b/Java/maven-war-plugin-JarArtifactStub_91/npe.json
new file mode 100644
index 000000000..858b5dc7c
--- /dev/null
+++ b/Java/maven-war-plugin-JarArtifactStub_91/npe.json
@@ -0,0 +1,7 @@
+{
+    "filepath": "src/test/java/org/apache/maven/plugins/war/stub/JarArtifactStub.java",
+    "line": 92,
+    "npe_method": "getVersion",
+    "deref_field": "version",
+    "npe_class": "JarArtifactStub"
+}
\ No newline at end of file
diff --git a/Java/maven-war-plugin-OverlayManager_200/Dockerfile b/Java/maven-war-plugin-OverlayManager_200/Dockerfile
new file mode 100644
index 000000000..34955205a
--- /dev/null
+++ b/Java/maven-war-plugin-OverlayManager_200/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:maven-war-plugin
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+    && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+    && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+    && mv /tmp/buggy.java $BUGGY_PATH \
+    && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/maven-war-plugin-OverlayManager_200/buggy.java b/Java/maven-war-plugin-OverlayManager_200/buggy.java
new file mode 100644
index 000000000..238828566
--- /dev/null
+++ b/Java/maven-war-plugin-OverlayManager_200/buggy.java
@@ -0,0 +1,256 @@
+package org.apache.maven.plugins.war.overlay;
+
+/*
+ * 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.
+ */
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Objects;
+import java.util.Set;
+
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
+import org.apache.maven.plugins.war.Overlay;
+import org.apache.maven.project.MavenProject;
+
+/**
+ * Manages the overlays.
+ *
+ * @author Stephane Nicoll
+ */
+public class OverlayManager
+{
+    private final List<Overlay> overlays;
+
+    private final MavenProject project;
+
+    private final List<Artifact> artifactsOverlays;
+
+    /**
+     * Creates a manager with the specified overlays.
+     * 
+     * Note that the list is potentially updated by the manager so a new list is created based on the overlays.
+     *
+     * @param overlays the overlays
+     * @param project the maven project
+     * @param defaultIncludes the default includes to use
+     * @param defaultExcludes the default excludes to use
+     * @param currentProjectOverlay the overlay for the current project
+     * @throws InvalidOverlayConfigurationException if the config is invalid
+     */
+    public OverlayManager( List<Overlay> overlays, MavenProject project, String[] defaultIncludes,
+                           String[] defaultExcludes, Overlay currentProjectOverlay )
+        throws InvalidOverlayConfigurationException
+    {
+        this.overlays = new ArrayList<>();
+        if ( overlays != null )
+        {
+            this.overlays.addAll( overlays );
+        }
+        this.project = project;
+
+        this.artifactsOverlays = getOverlaysAsArtifacts();
+
+        // Initialize
+        initialize( defaultIncludes, defaultExcludes, currentProjectOverlay );
+
+    }
+
+    /**
+     * Returns the resolved overlays.
+     *
+     * @return the overlays
+     */
+    public List<Overlay> getOverlays()
+    {
+        return overlays;
+    }
+
+    /**
+     * Returns the id of the resolved overlays.
+     *
+     * @return the overlay ids
+     */
+    public List<String> getOverlayIds()
+    {
+        final List<String> result = new ArrayList<>();
+        for ( Overlay overlay : overlays )
+        {
+            result.add( overlay.getId() );
+        }
+        return result;
+
+    }
+
+    /**
+     * Initializes the manager and validates the overlays configuration.
+     *
+     * @param defaultIncludes the default includes to use
+     * @param defaultExcludes the default excludes to use
+     * @param currentProjectOverlay the overlay for the current project
+     * @throws InvalidOverlayConfigurationException if the configuration is invalid
+     */
+    void initialize( String[] defaultIncludes, String[] defaultExcludes, Overlay currentProjectOverlay )
+        throws InvalidOverlayConfigurationException
+    {
+
+        // Build the list of configured artifacts and makes sure that each overlay
+        // refer to a valid artifact
+        final List<Artifact> configuredWarArtifacts = new ArrayList<>();
+        final ListIterator<Overlay> it = overlays.listIterator();
+        while ( it.hasNext() )
+        {
+            Overlay overlay = it.next();
+            if ( overlay == null )
+            {
+                throw new InvalidOverlayConfigurationException( "overlay could not be null." );
+            }
+            // If it's the current project, return the project instance
+            if ( overlay.isCurrentProject() )
+            {
+                overlay = currentProjectOverlay;
+                it.set( overlay );
+            }
+            // default includes/excludes - only if the overlay uses the default settings
+            if ( Arrays.equals( Overlay.DEFAULT_INCLUDES, overlay.getIncludes() )
+                && Arrays.equals( Overlay.DEFAULT_EXCLUDES, overlay.getExcludes() ) )
+            {
+                overlay.setIncludes( defaultIncludes );
+                overlay.setExcludes( defaultExcludes );
+            }
+
+            final Artifact artifact = getAssociatedArtifact( overlay );
+            if ( artifact != null )
+            {
+                configuredWarArtifacts.add( artifact );
+                overlay.setArtifact( artifact );
+            }
+        }
+
+        // Build the list of missing overlays
+        for ( Artifact artifact : artifactsOverlays )
+        {
+            if ( !configuredWarArtifacts.contains( artifact ) )
+            {
+                // Add a default overlay for the given artifact which will be applied after
+                // the ones that have been configured
+                overlays.add( new DefaultOverlay( artifact, defaultIncludes, defaultExcludes ) );
+            }
+        }
+
+        // Final validation, make sure that the current project is in there. Otherwise add it first
+        for ( Overlay overlay : overlays )
+        {
+            if ( overlay.equals( currentProjectOverlay ) )
+            {
+                return;
+            }
+        }
+        overlays.add( 0, currentProjectOverlay );
+    }
+
+    /**
+     * Returns the Artifact associated to the specified overlay.
+     * 
+     * If the overlay defines the current project, <tt>null</tt> is returned. If no artifact could not be found for the
+     * overlay a InvalidOverlayConfigurationException is thrown.
+     *
+     * @param overlay an overlay
+     * @return the artifact associated to the overlay
+     * @throws org.apache.maven.plugins.war.overlay.InvalidOverlayConfigurationException if the overlay does not have an
+     *             associated artifact
+     */
+/**
+ * Returns the Artifact associated to the specified overlay.
+ *
+ * If the overlay defines the current project, <tt>null</tt> is returned. If no artifact could not be found for the
+ * overlay a InvalidOverlayConfigurationException is thrown.
+ *
+ * @param overlay
+ * 		an overlay
+ * @return the artifact associated to the overlay
+ * @throws org.apache.maven.plugins.war.overlay.InvalidOverlayConfigurationException
+ * 		if the overlay does not have an
+ * 		associated artifact
+ */
+org.apache.maven.artifact.Artifact getAssociatedArtifact(final org.apache.maven.plugins.war.Overlay overlay) throws org.apache.maven.plugins.war.overlay.InvalidOverlayConfigurationException {
+    if (overlay.isCurrentProject()) {
+        return null;
+    }
+    for (org.apache.maven.artifact.Artifact artifact : artifactsOverlays) {
+        // Handle classifier dependencies properly (clash management)
+        if (compareOverlayWithArtifact(overlay, artifact)) {
+            return artifact;
+        }
+    }
+    // maybe its a project dependencies zip or an other type
+    java.util.Set<org.apache.maven.artifact.Artifact> projectArtifacts = this.project.getDependencyArtifacts();
+    {
+        for (org.apache.maven.artifact.Artifact artifact : /* NPEX_NULL_EXP */
+        projectArtifacts) {
+            if (compareOverlayWithArtifact(overlay, artifact)) {
+                return artifact;
+            }
+        }
+    }
+    // CHECKSTYLE_OFF: LineLength
+    throw new org.apache.maven.plugins.war.overlay.InvalidOverlayConfigurationException(("overlay [" + overlay) + "] is not a dependency of the project.");
+    // CHECKSTYLE_ON: LineLength
+}
+
+    /**
+     * Compare groupId && artifactId && type && classifier.
+     *
+     * @param overlay the overlay
+     * @param artifact the artifact
+     * @return boolean true if equals
+     */
+    private boolean compareOverlayWithArtifact( Overlay overlay, Artifact artifact )
+    {
+        return ( Objects.equals( overlay.getGroupId(), artifact.getGroupId() )
+            && Objects.equals( overlay.getArtifactId(), artifact.getArtifactId() )
+            && Objects.equals( overlay.getType(), artifact.getType() )
+        // MWAR-241 Make sure to treat null and "" as equal when comparing the classifier
+        && Objects.equals( Objects.toString( overlay.getClassifier() ),
+                           Objects.toString( artifact.getClassifier() ) ) );
+    }
+
+    /**
+     * Returns a list of WAR {@link org.apache.maven.artifact.Artifact} describing the overlays of the current project.
+     *
+     * @return the overlays as artifacts objects
+     */
+    private List<Artifact> getOverlaysAsArtifacts()
+    {
+        ScopeArtifactFilter filter = new ScopeArtifactFilter( Artifact.SCOPE_RUNTIME );
+        final Set<Artifact> artifacts = project.getArtifacts();
+
+        final List<Artifact> result = new ArrayList<>();
+        for ( Artifact artifact : artifacts )
+        {
+            if ( !artifact.isOptional() && filter.include( artifact ) && ( "war".equals( artifact.getType() ) ) )
+            {
+                result.add( artifact );
+            }
+        }
+        return result;
+    }
+}
diff --git a/Java/maven-war-plugin-OverlayManager_200/metadata.json b/Java/maven-war-plugin-OverlayManager_200/metadata.json
new file mode 100644
index 000000000..119289202
--- /dev/null
+++ b/Java/maven-war-plugin-OverlayManager_200/metadata.json
@@ -0,0 +1,21 @@
+{
+  "language": "java",
+  "id": "maven-war-plugin-OverlayManager_200",
+  "buggyPath": ".",
+  "referencePath": null,
+  "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+  "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+  "categories": [
+    "safety",
+    "npe"
+  ],
+  "npe": {
+    "filepath": "src/main/java/org/apache/maven/plugins/war/overlay/OverlayManager.java",
+    "line": 208,
+    "npe_method": "getAssociatedArtifact",
+    "deref_field": "projectArtifacts",
+    "npe_class": "OverlayManager",
+    "repo": "maven-war-plugin",
+    "bug_id": "OverlayManager_200"
+  }
+}
diff --git a/Java/maven-war-plugin-OverlayManager_200/npe.json b/Java/maven-war-plugin-OverlayManager_200/npe.json
new file mode 100644
index 000000000..28847e1d7
--- /dev/null
+++ b/Java/maven-war-plugin-OverlayManager_200/npe.json
@@ -0,0 +1,7 @@
+{
+    "filepath": "src/main/java/org/apache/maven/plugins/war/overlay/OverlayManager.java",
+    "line": 208,
+    "npe_method": "getAssociatedArtifact",
+    "deref_field": "projectArtifacts",
+    "npe_class": "OverlayManager"
+}
\ No newline at end of file
diff --git a/Java/maven-war-plugin-OverlayPackagingTask_80/Dockerfile b/Java/maven-war-plugin-OverlayPackagingTask_80/Dockerfile
new file mode 100644
index 000000000..34955205a
--- /dev/null
+++ b/Java/maven-war-plugin-OverlayPackagingTask_80/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:maven-war-plugin
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+    && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+    && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+    && mv /tmp/buggy.java $BUGGY_PATH \
+    && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/maven-war-plugin-OverlayPackagingTask_80/buggy.java b/Java/maven-war-plugin-OverlayPackagingTask_80/buggy.java
new file mode 100644
index 000000000..1c25b794b
--- /dev/null
+++ b/Java/maven-war-plugin-OverlayPackagingTask_80/buggy.java
@@ -0,0 +1,139 @@
+package org.apache.maven.plugins.war.packaging;
+
+/*
+ * 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.
+ */
+
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugins.war.Overlay;
+import org.apache.maven.plugins.war.util.PathSet;
+import org.codehaus.plexus.util.FileUtils;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * Handles an overlay.
+ *
+ * @author Stephane Nicoll
+ */
+public class OverlayPackagingTask
+    extends AbstractWarPackagingTask
+{
+    private final Overlay overlay;
+
+    /**
+     * @param overlay {@link #overlay}
+     * @param currentProjectOverlay current overlay.
+     */
+    public OverlayPackagingTask( Overlay overlay, Overlay currentProjectOverlay )
+    {
+        if ( overlay == null )
+        {
+            throw new NullPointerException( "overlay could not be null." );
+        }
+        if ( overlay.equals( currentProjectOverlay ) )
+        {
+            throw new IllegalStateException( "Could not handle the current project with this task." );
+        }
+        this.overlay = overlay;
+    }
+
+    @Override
+public void performPackaging(org.apache.maven.plugins.war.packaging.WarPackagingContext context) throws org.apache.maven.plugin.MojoExecutionException {
+    context.getLog().debug("OverlayPackagingTask performPackaging overlay.getTargetPath() " + overlay.getTargetPath());
+    if (overlay.shouldSkip()) {
+        context.getLog().info(("Skipping overlay [" + overlay) + "]");
+    } else {
+        try {
+            context.getLog().info(("Processing overlay [" + overlay) + "]");
+            // Step1: Extract if necessary
+            final java.io.File tmpDir = unpackOverlay(context, overlay);
+            // Step2: setup
+            final org.apache.maven.plugins.war.util.PathSet includes = getFilesToIncludes(tmpDir, overlay.getIncludes(), overlay.getExcludes());
+            {
+                // overlay.getTargetPath() must ended with /
+                // if not we add it
+                java.lang.String targetPath = /* NPEX_NULL_EXP */
+                overlay.getTargetPath();
+                if (!targetPath.endsWith("/")) {
+                    targetPath = targetPath + "/";
+                }
+                copyFiles(overlay.getId(), context, tmpDir, includes, targetPath, overlay.isFiltered());
+            }
+        } catch (java.io.IOException e) {
+            throw new org.apache.maven.plugin.MojoExecutionException(("Failed to copy file for overlay [" + overlay) + "]", e);
+        }
+    }
+}
+
+    /**
+     * Unpacks the specified overlay.
+     * 
+     * Makes sure to skip the unpack process if the overlay has already been unpacked.
+     *
+     * @param context the packaging context
+     * @param overlay the overlay
+     * @return the directory containing the unpacked overlay
+     * @throws MojoExecutionException if an error occurred while unpacking the overlay
+     */
+    protected File unpackOverlay( WarPackagingContext context, Overlay overlay )
+        throws MojoExecutionException
+    {
+        final File tmpDir = getOverlayTempDirectory( context, overlay );
+
+        // TODO: not sure it's good, we should reuse the markers of the dependency plugin
+        if ( FileUtils.sizeOfDirectory( tmpDir ) == 0
+            || overlay.getArtifact().getFile().lastModified() > tmpDir.lastModified() )
+        {
+            doUnpack( context, overlay.getArtifact().getFile(), tmpDir );
+        }
+        else
+        {
+            context.getLog().debug( "Overlay [" + overlay + "] was already unpacked" );
+        }
+        return tmpDir;
+    }
+
+    /**
+     * Returns the directory to use to unpack the specified overlay.
+     *
+     * @param context the packaging context
+     * @param overlay the overlay
+     * @return the temp directory for the overlay
+     */
+    protected File getOverlayTempDirectory( WarPackagingContext context, Overlay overlay )
+    {
+        final File groupIdDir = new File( context.getOverlaysWorkDirectory(), overlay.getGroupId() );
+        if ( !groupIdDir.exists() )
+        {
+            groupIdDir.mkdir();
+        }
+        String directoryName = overlay.getArtifactId();
+        if ( overlay.getClassifier() != null )
+        {
+            directoryName = directoryName + "-" + overlay.getClassifier();
+        }
+        final File result = new File( groupIdDir, directoryName );
+        if ( !result.exists() )
+        {
+            result.mkdirs();
+        }
+        return result;
+    }
+}
diff --git a/Java/maven-war-plugin-OverlayPackagingTask_80/metadata.json b/Java/maven-war-plugin-OverlayPackagingTask_80/metadata.json
new file mode 100644
index 000000000..4022306d1
--- /dev/null
+++ b/Java/maven-war-plugin-OverlayPackagingTask_80/metadata.json
@@ -0,0 +1,21 @@
+{
+  "language": "java",
+  "id": "maven-war-plugin-OverlayPackagingTask_80",
+  "buggyPath": ".",
+  "referencePath": null,
+  "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+  "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+  "categories": [
+    "safety",
+    "npe"
+  ],
+  "npe": {
+    "filepath": "src/main/java/org/apache/maven/plugins/war/packaging/OverlayPackagingTask.java",
+    "line": 73,
+    "npe_method": "performPackaging",
+    "deref_field": "getTargetPath",
+    "npe_class": "OverlayPackagingTask",
+    "repo": "maven-war-plugin",
+    "bug_id": "OverlayPackagingTask_80"
+  }
+}
diff --git a/Java/maven-war-plugin-OverlayPackagingTask_80/npe.json b/Java/maven-war-plugin-OverlayPackagingTask_80/npe.json
new file mode 100644
index 000000000..8a13aedbc
--- /dev/null
+++ b/Java/maven-war-plugin-OverlayPackagingTask_80/npe.json
@@ -0,0 +1,7 @@
+{
+    "filepath": "src/main/java/org/apache/maven/plugins/war/packaging/OverlayPackagingTask.java",
+    "line": 73,
+    "npe_method": "performPackaging",
+    "deref_field": "getTargetPath",
+    "npe_class": "OverlayPackagingTask"
+}
\ No newline at end of file
diff --git a/Java/maven-war-plugin-WarArtifactStub_51/Dockerfile b/Java/maven-war-plugin-WarArtifactStub_51/Dockerfile
new file mode 100644
index 000000000..34955205a
--- /dev/null
+++ b/Java/maven-war-plugin-WarArtifactStub_51/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:maven-war-plugin
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+    && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+    && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+    && mv /tmp/buggy.java $BUGGY_PATH \
+    && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/maven-war-plugin-WarArtifactStub_51/buggy.java b/Java/maven-war-plugin-WarArtifactStub_51/buggy.java
new file mode 100644
index 000000000..3da998746
--- /dev/null
+++ b/Java/maven-war-plugin-WarArtifactStub_51/buggy.java
@@ -0,0 +1,110 @@
+package org.apache.maven.plugins.war.stub;
+
+/*
+ * 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.
+ */
+
+import java.io.File;
+
+/**
+ * Stub
+ */
+public class WarArtifactStub
+    extends AbstractArtifactStub
+{
+
+    private String groupId;
+
+    private String artifactId;
+
+    private String classifier;
+
+    private File file;
+
+    public WarArtifactStub( String _basedir )
+    {
+        super( _basedir );
+    }
+
+    public String getType()
+    {
+        return "war";
+    }
+
+public java.lang.String getArtifactId() {
+    {
+        return /* NPEX_NULL_EXP */
+        artifactId;
+    }
+}
+
+    public void setArtifactId( String _artifactId )
+    {
+        artifactId = _artifactId;
+    }
+
+
+    public String getGroupId()
+    {
+        if ( groupId == null )
+        {
+            return "wartests";
+        }
+        else
+        {
+            return groupId;
+        }
+    }
+
+    public void setGroupId( String groupId )
+    {
+        this.groupId = groupId;
+    }
+
+    public File getFile()
+    {
+        if ( file == null )
+        {
+            return new File( basedir, "/target/test-classes/unit/sample_wars/simple.war" );
+        }
+        else
+        {
+            return file;
+        }
+    }
+
+    public void setFile( File _file )
+    {
+        file = _file;
+    }
+
+    public String getClassifier()
+    {
+        return classifier;
+    }
+
+    public void setClassifier( String classifier )
+    {
+        this.classifier = classifier;
+    }
+
+    public boolean hasClassifier()
+    {
+        return classifier != null;
+    }
+}
diff --git a/Java/maven-war-plugin-WarArtifactStub_51/metadata.json b/Java/maven-war-plugin-WarArtifactStub_51/metadata.json
new file mode 100644
index 000000000..0ccf7a784
--- /dev/null
+++ b/Java/maven-war-plugin-WarArtifactStub_51/metadata.json
@@ -0,0 +1,21 @@
+{
+  "language": "java",
+  "id": "maven-war-plugin-WarArtifactStub_51",
+  "buggyPath": ".",
+  "referencePath": null,
+  "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+  "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+  "categories": [
+    "safety",
+    "npe"
+  ],
+  "npe": {
+    "filepath": "src/test/java/org/apache/maven/plugins/war/stub/WarArtifactStub.java",
+    "line": 52,
+    "npe_method": "getArtifactId",
+    "deref_field": "artifactId",
+    "npe_class": "WarArtifactStub",
+    "repo": "maven-war-plugin",
+    "bug_id": "WarArtifactStub_51"
+  }
+}
diff --git a/Java/maven-war-plugin-WarArtifactStub_51/npe.json b/Java/maven-war-plugin-WarArtifactStub_51/npe.json
new file mode 100644
index 000000000..25554f83c
--- /dev/null
+++ b/Java/maven-war-plugin-WarArtifactStub_51/npe.json
@@ -0,0 +1,7 @@
+{
+    "filepath": "src/test/java/org/apache/maven/plugins/war/stub/WarArtifactStub.java",
+    "line": 52,
+    "npe_method": "getArtifactId",
+    "deref_field": "artifactId",
+    "npe_class": "WarArtifactStub"
+}
\ No newline at end of file
diff --git a/Java/maven-war-plugin-WarArtifactStub_69/Dockerfile b/Java/maven-war-plugin-WarArtifactStub_69/Dockerfile
new file mode 100644
index 000000000..34955205a
--- /dev/null
+++ b/Java/maven-war-plugin-WarArtifactStub_69/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:maven-war-plugin
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+    && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+    && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+    && mv /tmp/buggy.java $BUGGY_PATH \
+    && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/maven-war-plugin-WarArtifactStub_69/buggy.java b/Java/maven-war-plugin-WarArtifactStub_69/buggy.java
new file mode 100644
index 000000000..b1e2c571b
--- /dev/null
+++ b/Java/maven-war-plugin-WarArtifactStub_69/buggy.java
@@ -0,0 +1,110 @@
+package org.apache.maven.plugins.war.stub;
+
+/*
+ * 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.
+ */
+
+import java.io.File;
+
+/**
+ * Stub
+ */
+public class WarArtifactStub
+    extends AbstractArtifactStub
+{
+
+    private String groupId;
+
+    private String artifactId;
+
+    private String classifier;
+
+    private File file;
+
+    public WarArtifactStub( String _basedir )
+    {
+        super( _basedir );
+    }
+
+    public String getType()
+    {
+        return "war";
+    }
+
+    public String getArtifactId()
+    {
+        if ( artifactId == null )
+        {
+            return "simple";
+        }
+        else
+        {
+            return artifactId;
+        }
+    }
+
+    public void setArtifactId( String _artifactId )
+    {
+        artifactId = _artifactId;
+    }
+
+
+public java.lang.String getGroupId() {
+    {
+        return /* NPEX_NULL_EXP */
+        groupId;
+    }
+}
+
+    public void setGroupId( String groupId )
+    {
+        this.groupId = groupId;
+    }
+
+    public File getFile()
+    {
+        if ( file == null )
+        {
+            return new File( basedir, "/target/test-classes/unit/sample_wars/simple.war" );
+        }
+        else
+        {
+            return file;
+        }
+    }
+
+    public void setFile( File _file )
+    {
+        file = _file;
+    }
+
+    public String getClassifier()
+    {
+        return classifier;
+    }
+
+    public void setClassifier( String classifier )
+    {
+        this.classifier = classifier;
+    }
+
+    public boolean hasClassifier()
+    {
+        return classifier != null;
+    }
+}
diff --git a/Java/maven-war-plugin-WarArtifactStub_69/metadata.json b/Java/maven-war-plugin-WarArtifactStub_69/metadata.json
new file mode 100644
index 000000000..b42544325
--- /dev/null
+++ b/Java/maven-war-plugin-WarArtifactStub_69/metadata.json
@@ -0,0 +1,21 @@
+{
+  "language": "java",
+  "id": "maven-war-plugin-WarArtifactStub_69",
+  "buggyPath": ".",
+  "referencePath": null,
+  "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+  "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+  "categories": [
+    "safety",
+    "npe"
+  ],
+  "npe": {
+    "filepath": "src/test/java/org/apache/maven/plugins/war/stub/WarArtifactStub.java",
+    "line": 70,
+    "npe_method": "getGroupId",
+    "deref_field": "groupId",
+    "npe_class": "WarArtifactStub",
+    "repo": "maven-war-plugin",
+    "bug_id": "WarArtifactStub_69"
+  }
+}
diff --git a/Java/maven-war-plugin-WarArtifactStub_69/npe.json b/Java/maven-war-plugin-WarArtifactStub_69/npe.json
new file mode 100644
index 000000000..a4fdcaaf8
--- /dev/null
+++ b/Java/maven-war-plugin-WarArtifactStub_69/npe.json
@@ -0,0 +1,7 @@
+{
+    "filepath": "src/test/java/org/apache/maven/plugins/war/stub/WarArtifactStub.java",
+    "line": 70,
+    "npe_method": "getGroupId",
+    "deref_field": "groupId",
+    "npe_class": "WarArtifactStub"
+}
\ No newline at end of file
diff --git a/Java/maven-war-plugin-WarArtifactStub_86/Dockerfile b/Java/maven-war-plugin-WarArtifactStub_86/Dockerfile
new file mode 100644
index 000000000..34955205a
--- /dev/null
+++ b/Java/maven-war-plugin-WarArtifactStub_86/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:maven-war-plugin
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+    && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+    && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+    && mv /tmp/buggy.java $BUGGY_PATH \
+    && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/maven-war-plugin-WarArtifactStub_86/buggy.java b/Java/maven-war-plugin-WarArtifactStub_86/buggy.java
new file mode 100644
index 000000000..d321ef40e
--- /dev/null
+++ b/Java/maven-war-plugin-WarArtifactStub_86/buggy.java
@@ -0,0 +1,110 @@
+package org.apache.maven.plugins.war.stub;
+
+/*
+ * 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.
+ */
+
+import java.io.File;
+
+/**
+ * Stub
+ */
+public class WarArtifactStub
+    extends AbstractArtifactStub
+{
+
+    private String groupId;
+
+    private String artifactId;
+
+    private String classifier;
+
+    private File file;
+
+    public WarArtifactStub( String _basedir )
+    {
+        super( _basedir );
+    }
+
+    public String getType()
+    {
+        return "war";
+    }
+
+    public String getArtifactId()
+    {
+        if ( artifactId == null )
+        {
+            return "simple";
+        }
+        else
+        {
+            return artifactId;
+        }
+    }
+
+    public void setArtifactId( String _artifactId )
+    {
+        artifactId = _artifactId;
+    }
+
+
+    public String getGroupId()
+    {
+        if ( groupId == null )
+        {
+            return "wartests";
+        }
+        else
+        {
+            return groupId;
+        }
+    }
+
+    public void setGroupId( String groupId )
+    {
+        this.groupId = groupId;
+    }
+
+public java.io.File getFile() {
+    {
+        return /* NPEX_NULL_EXP */
+        file;
+    }
+}
+
+    public void setFile( File _file )
+    {
+        file = _file;
+    }
+
+    public String getClassifier()
+    {
+        return classifier;
+    }
+
+    public void setClassifier( String classifier )
+    {
+        this.classifier = classifier;
+    }
+
+    public boolean hasClassifier()
+    {
+        return classifier != null;
+    }
+}
diff --git a/Java/maven-war-plugin-WarArtifactStub_86/metadata.json b/Java/maven-war-plugin-WarArtifactStub_86/metadata.json
new file mode 100644
index 000000000..e2d5de83a
--- /dev/null
+++ b/Java/maven-war-plugin-WarArtifactStub_86/metadata.json
@@ -0,0 +1,21 @@
+{
+  "language": "java",
+  "id": "maven-war-plugin-WarArtifactStub_86",
+  "buggyPath": ".",
+  "referencePath": null,
+  "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+  "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+  "categories": [
+    "safety",
+    "npe"
+  ],
+  "npe": {
+    "filepath": "src/test/java/org/apache/maven/plugins/war/stub/WarArtifactStub.java",
+    "line": 87,
+    "npe_method": "getFile",
+    "deref_field": "file",
+    "npe_class": "WarArtifactStub",
+    "repo": "maven-war-plugin",
+    "bug_id": "WarArtifactStub_86"
+  }
+}
diff --git a/Java/maven-war-plugin-WarArtifactStub_86/npe.json b/Java/maven-war-plugin-WarArtifactStub_86/npe.json
new file mode 100644
index 000000000..f20ce5359
--- /dev/null
+++ b/Java/maven-war-plugin-WarArtifactStub_86/npe.json
@@ -0,0 +1,7 @@
+{
+    "filepath": "src/test/java/org/apache/maven/plugins/war/stub/WarArtifactStub.java",
+    "line": 87,
+    "npe_method": "getFile",
+    "deref_field": "file",
+    "npe_class": "WarArtifactStub"
+}
\ No newline at end of file
diff --git a/Java/maven-war-plugin-WarMojo_349/Dockerfile b/Java/maven-war-plugin-WarMojo_349/Dockerfile
new file mode 100644
index 000000000..34955205a
--- /dev/null
+++ b/Java/maven-war-plugin-WarMojo_349/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:maven-war-plugin
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+    && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+    && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+    && mv /tmp/buggy.java $BUGGY_PATH \
+    && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/maven-war-plugin-WarMojo_349/buggy.java b/Java/maven-war-plugin-WarMojo_349/buggy.java
new file mode 100644
index 000000000..7b67e1b04
--- /dev/null
+++ b/Java/maven-war-plugin-WarMojo_349/buggy.java
@@ -0,0 +1,583 @@
+package org.apache.maven.plugins.war;
+
+/*
+ * 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.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.maven.archiver.MavenArchiver;
+import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.DependencyResolutionRequiredException;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.Component;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.plugins.annotations.ResolutionScope;
+import org.apache.maven.plugins.war.util.ClassesPackager;
+import org.apache.maven.project.MavenProjectHelper;
+import org.codehaus.plexus.archiver.Archiver;
+import org.codehaus.plexus.archiver.ArchiverException;
+import org.codehaus.plexus.archiver.jar.ManifestException;
+import org.codehaus.plexus.archiver.war.WarArchiver;
+import org.codehaus.plexus.util.FileUtils;
+import org.codehaus.plexus.util.StringUtils;
+
+/**
+ * Build a WAR file.
+ *
+ * @author <a href="evenisse@apache.org">Emmanuel Venisse</a>
+ */
+@Mojo( name = "war", defaultPhase = LifecyclePhase.PACKAGE, threadSafe = true,
+                requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME )
+public class WarMojo
+    extends AbstractWarMojo
+{
+    /**
+     * The directory for the generated WAR.
+     */
+    @Parameter( defaultValue = "${project.build.directory}", required = true )
+    private String outputDirectory;
+
+    /**
+     * The name of the generated WAR.
+     */
+    @Parameter( defaultValue = "${project.build.finalName}", required = true, readonly = true )
+    private String warName;
+
+    /**
+     * Classifier to add to the generated WAR. If given, the artifact will be an attachment instead. The classifier will
+     * not be applied to the JAR file of the project - only to the WAR file.
+     */
+    @Parameter
+    private String classifier;
+
+    /**
+     * The comma separated list of tokens to exclude from the WAR before packaging. This option may be used to implement
+     * the skinny WAR use case. Note that you can use the Java Regular Expressions engine to include and exclude
+     * specific pattern using the expression %regex[]. Hint: read the about (?!Pattern).
+     *
+     * @since 2.1-alpha-2
+     */
+    @Parameter
+    private String packagingExcludes;
+
+    /**
+     * The comma separated list of tokens to include in the WAR before packaging. By default everything is included.
+     * This option may be used to implement the skinny WAR use case. Note that you can use the Java Regular Expressions
+     * engine to include and exclude specific pattern using the expression %regex[].
+     *
+     * @since 2.1-beta-1
+     */
+    @Parameter
+    private String packagingIncludes;
+
+    /**
+     * The WAR archiver.
+     */
+    @Component( role = Archiver.class, hint = "war" )
+    private WarArchiver warArchiver;
+
+    /**
+     */
+    @Component
+    private MavenProjectHelper projectHelper;
+
+    /**
+     * Whether this is the main artifact being built. Set to <code>false</code> if you don't want to install or deploy
+     * it to the local repository instead of the default one in an execution.
+     */
+    @Parameter( defaultValue = "true" )
+    private boolean primaryArtifact;
+
+    /**
+     * Whether classes (that is the content of the WEB-INF/classes directory) should be attached to the project as an
+     * additional artifact.
+     * <p>
+     * By default the classifier for the additional artifact is 'classes'. You can change it with the
+     * <code><![CDATA[<classesClassifier>someclassifier</classesClassifier>]]></code> parameter.
+     * </p>
+     * <p>
+     * If this parameter true, another project can depend on the classes by writing something like:
+     *
+     * <pre>
+     * <![CDATA[<dependency>
+     *   <groupId>myGroup</groupId>
+     *   <artifactId>myArtifact</artifactId>
+     *   <version>myVersion</myVersion>
+     *   <classifier>classes</classifier>
+     * </dependency>]]>
+     * </pre>
+     * </p>
+     *
+     * @since 2.1-alpha-2
+     */
+    @Parameter( defaultValue = "false" )
+    private boolean attachClasses;
+
+    /**
+     * The classifier to use for the attached classes artifact.
+     *
+     * @since 2.1-alpha-2
+     */
+    @Parameter( defaultValue = "classes" )
+    private String classesClassifier;
+
+    /**
+     * You can skip the execution of the plugin if you need to. Its use is NOT RECOMMENDED, but quite convenient on
+     * occasion.
+     *
+     * @since 3.0.0
+     */
+    @Parameter( property = "maven.war.skip", defaultValue = "false" )
+    private boolean skip;
+
+    // ----------------------------------------------------------------------
+    // Implementation
+    // ----------------------------------------------------------------------
+
+    /**
+     * Executes the WarMojo on the current project.
+     *
+     * @throws MojoExecutionException if an error occurred while building the webapp
+     * @throws MojoFailureException if an error.
+     */
+    @Override
+    public void execute()
+        throws MojoExecutionException, MojoFailureException
+    {
+
+        if ( isSkip() )
+        {
+            getLog().info( "Skipping the execution." );
+            return;
+        }
+
+        File warFile = getTargetWarFile();
+
+        try
+        {
+            performPackaging( warFile );
+        }
+        catch ( DependencyResolutionRequiredException | ArchiverException e )
+        {
+            throw new MojoExecutionException( "Error assembling WAR: " + e.getMessage(), e );
+        }
+        catch ( ManifestException | IOException e )
+        {
+            throw new MojoExecutionException( "Error assembling WAR", e );
+        }
+    }
+
+    /**
+     * Generates the webapp according to the <tt>mode</tt> attribute.
+     *
+     * @param warFile the target WAR file
+     * @throws IOException if an error occurred while copying files
+     * @throws ArchiverException if the archive could not be created
+     * @throws ManifestException if the manifest could not be created
+     * @throws DependencyResolutionRequiredException if an error occurred while resolving the dependencies
+     * @throws MojoExecutionException if the execution failed
+     * @throws MojoFailureException if a fatal exception occurred
+     */
+    private void performPackaging( File warFile )
+        throws IOException, ManifestException, DependencyResolutionRequiredException, MojoExecutionException,
+        MojoFailureException
+    {
+        getLog().info( "Packaging webapp" );
+
+        buildExplodedWebapp( getWebappDirectory() );
+
+        MavenArchiver archiver = new MavenArchiver();
+
+        archiver.setArchiver( warArchiver );
+
+        archiver.setCreatedBy( "Maven WAR Plugin", "org.apache.maven.plugins", "maven-war-plugin" );
+
+        archiver.setOutputFile( warFile );
+
+        // configure for Reproducible Builds based on outputTimestamp value
+        archiver.configureReproducible( outputTimestamp );
+
+        getLog().debug( "Excluding " + Arrays.asList( getPackagingExcludes() )
+            + " from the generated webapp archive." );
+        getLog().debug( "Including " + Arrays.asList( getPackagingIncludes() ) + " in the generated webapp archive." );
+
+        warArchiver.addDirectory( getWebappDirectory(), getPackagingIncludes(), getPackagingExcludes() );
+
+        final File webXmlFile = new File( getWebappDirectory(), "WEB-INF/web.xml" );
+        if ( webXmlFile.exists() )
+        {
+            warArchiver.setWebxml( webXmlFile );
+        }
+
+        warArchiver.setRecompressAddedZips( isRecompressZippedFiles() );
+
+        warArchiver.setIncludeEmptyDirs( isIncludeEmptyDirectories() );
+
+        if ( Boolean.FALSE.equals( failOnMissingWebXml )
+            || ( failOnMissingWebXml == null && isProjectUsingAtLeastServlet30() ) )
+        {
+            getLog().debug( "Build won't fail if web.xml file is missing." );
+            warArchiver.setExpectWebXml( false );
+        }
+
+        // create archive
+        archiver.createArchive( getSession(), getProject(), getArchive() );
+
+        // create the classes to be attached if necessary
+        if ( isAttachClasses() )
+        {
+            if ( isArchiveClasses() && getJarArchiver().getDestFile() != null )
+            {
+                // special handling in case of archived classes: MWAR-240
+                File targetClassesFile = getTargetClassesFile();
+                FileUtils.copyFile( getJarArchiver().getDestFile(), targetClassesFile );
+                projectHelper.attachArtifact( getProject(), "jar", getClassesClassifier(), targetClassesFile );
+            }
+            else
+            {
+                ClassesPackager packager = new ClassesPackager();
+                final File classesDirectory = packager.getClassesDirectory( getWebappDirectory() );
+                if ( classesDirectory.exists() )
+                {
+                    getLog().info( "Packaging classes" );
+                    packager.packageClasses( classesDirectory, getTargetClassesFile(), getJarArchiver(), getSession(),
+                                             getProject(), getArchive(), outputTimestamp );
+                    projectHelper.attachArtifact( getProject(), "jar", getClassesClassifier(), getTargetClassesFile() );
+                }
+            }
+        }
+
+        if ( this.classifier != null )
+        {
+            projectHelper.attachArtifact( getProject(), "war", this.classifier, warFile );
+        }
+        else
+        {
+            Artifact artifact = getProject().getArtifact();
+            if ( primaryArtifact )
+            {
+                artifact.setFile( warFile );
+            }
+            else if ( artifact.getFile() == null || artifact.getFile().isDirectory() )
+            {
+                artifact.setFile( warFile );
+            }
+        }
+    }
+
+    /**
+     * Determines if the current Maven project being built uses the Servlet 3.0 API (JSR 315)
+     * or Jakarta Servlet API.
+     * If it does then the <code>web.xml</code> file can be omitted.
+     * <p>
+     * This is done by checking if the interface <code>javax.servlet.annotation.WebServlet</code>
+     * or <code>jakarta.servlet.annotation.WebServlet</code> is in the compile-time
+     * dependencies (which includes provided dependencies) of the Maven project.
+     *
+     * @return <code>true</code> if the project being built depends on Servlet 3.0 API or Jakarta Servlet API,
+     *         <code>false</code> otherwise.
+     * @throws DependencyResolutionRequiredException if the compile elements can't be resolved.
+     * @throws MalformedURLException if the path to a dependency file can't be transformed to a URL.
+     */
+    private boolean isProjectUsingAtLeastServlet30()
+        throws DependencyResolutionRequiredException, MalformedURLException
+    {
+        List<String> classpathElements = getProject().getCompileClasspathElements();
+        URL[] urls = new URL[classpathElements.size()];
+        for ( int i = 0; i < urls.length; i++ )
+        {
+            urls[i] = new File( classpathElements.get( i ) ).toURI().toURL();
+        }
+        ClassLoader loader = new URLClassLoader( urls, Thread.currentThread().getContextClassLoader() );
+
+        return hasWebServletAnnotationClassInClasspath( loader );
+    }
+
+    private static boolean hasWebServletAnnotationClassInClasspath( ClassLoader loader )
+    {
+        return hasClassInClasspath( loader, "javax.servlet.annotation.WebServlet" )
+                || hasClassInClasspath( loader, "jakarta.servlet.annotation.WebServlet" );
+    }
+
+    private static boolean hasClassInClasspath( ClassLoader loader, String clazz )
+    {
+        try
+        {
+            Class.forName( clazz, false, loader );
+            return true;
+        }
+        catch ( ClassNotFoundException e )
+        {
+            return false;
+        }
+    }
+
+    /**
+     * @param basedir The basedir
+     * @param finalName The finalName
+     * @param classifier The classifier.
+     * @param type The type.
+     * @return {@link File}
+     */
+/**
+ *
+ *
+ * @param basedir
+ * 		The basedir
+ * @param finalName
+ * 		The finalName
+ * @param classifier
+ * 		The classifier.
+ * @param type
+ * 		The type.
+ * @return {@link File}
+ */
+protected static java.io.File getTargetFile(java.io.File basedir, java.lang.String finalName, java.lang.String classifier, java.lang.String type) {
+    {
+        if ((/* NPEX_NULL_EXP */
+        classifier.trim().length() > 0) && (!classifier.startsWith("-"))) {
+            classifier = "-" + classifier;
+        }
+    }
+    return new java.io.File(basedir, ((finalName + classifier) + ".") + type);
+}
+
+    /**
+     * @return The war {@link File}
+     */
+    protected File getTargetWarFile()
+    {
+        return getTargetFile( new File( getOutputDirectory() ), getWarName(), getClassifier(), "war" );
+
+    }
+
+    /**
+     * @return The target class {@link File}
+     */
+    protected File getTargetClassesFile()
+    {
+        return getTargetFile( new File( getOutputDirectory() ), getWarName(), getClassesClassifier(), "jar" );
+    }
+
+    // Getters and Setters
+
+    /**
+     * @return {@link #classifier}
+     */
+    public String getClassifier()
+    {
+        return classifier;
+    }
+
+    /**
+     * @param classifier {@link #classifier}
+     */
+    public void setClassifier( String classifier )
+    {
+        this.classifier = classifier;
+    }
+
+    /**
+     * @return The package excludes.
+     */
+    public String[] getPackagingExcludes()
+    {
+        if ( StringUtils.isEmpty( packagingExcludes ) )
+        {
+            return new String[0];
+        }
+        else
+        {
+            return StringUtils.split( packagingExcludes, "," );
+        }
+    }
+
+    /**
+     * @param packagingExcludes {@link #packagingExcludes}
+     */
+    public void setPackagingExcludes( String packagingExcludes )
+    {
+        this.packagingExcludes = packagingExcludes;
+    }
+
+    /**
+     * @return The packaging includes.
+     */
+    public String[] getPackagingIncludes()
+    {
+        if ( StringUtils.isEmpty( packagingIncludes ) )
+        {
+            return new String[] { "**" };
+        }
+        else
+        {
+            return StringUtils.split( packagingIncludes, "," );
+        }
+    }
+
+    /**
+     * @param packagingIncludes {@link #packagingIncludes}
+     */
+    public void setPackagingIncludes( String packagingIncludes )
+    {
+        this.packagingIncludes = packagingIncludes;
+    }
+
+    /**
+     * @return {@link #outputDirectory}
+     */
+    public String getOutputDirectory()
+    {
+        return outputDirectory;
+    }
+
+    /**
+     * @param outputDirectory {@link #outputDirectory}
+     */
+    public void setOutputDirectory( String outputDirectory )
+    {
+        this.outputDirectory = outputDirectory;
+    }
+
+    /**
+     * @return {@link #warName}
+     */
+    public String getWarName()
+    {
+        return warName;
+    }
+
+    /**
+     * @param warName {@link #warName}
+     */
+    public void setWarName( String warName )
+    {
+        this.warName = warName;
+    }
+
+    /**
+     * @return {@link #warArchiver}
+     */
+    public WarArchiver getWarArchiver()
+    {
+        return warArchiver;
+    }
+
+    /**
+     * @param warArchiver {@link #warArchiver}
+     */
+    public void setWarArchiver( WarArchiver warArchiver )
+    {
+        this.warArchiver = warArchiver;
+    }
+
+    /**
+     * @return {@link #projectHelper}
+     */
+    public MavenProjectHelper getProjectHelper()
+    {
+        return projectHelper;
+    }
+
+    /**
+     * @param projectHelper {@link #projectHelper}
+     */
+    public void setProjectHelper( MavenProjectHelper projectHelper )
+    {
+        this.projectHelper = projectHelper;
+    }
+
+    /**
+     * @return {@link #primaryArtifact}
+     */
+    public boolean isPrimaryArtifact()
+    {
+        return primaryArtifact;
+    }
+
+    /**
+     * @param primaryArtifact {@link #primaryArtifact}
+     */
+    public void setPrimaryArtifact( boolean primaryArtifact )
+    {
+        this.primaryArtifact = primaryArtifact;
+    }
+
+    /**
+     * @return {@link #attachClasses}
+     */
+    public boolean isAttachClasses()
+    {
+        return attachClasses;
+    }
+
+    /**
+     * @param attachClasses {@link #attachClasses}
+     */
+    public void setAttachClasses( boolean attachClasses )
+    {
+        this.attachClasses = attachClasses;
+    }
+
+    /**
+     * @return {@link #classesClassifier}
+     */
+    public String getClassesClassifier()
+    {
+        return classesClassifier;
+    }
+
+    /**
+     * @param classesClassifier {@link #classesClassifier}
+     */
+    public void setClassesClassifier( String classesClassifier )
+    {
+        this.classesClassifier = classesClassifier;
+    }
+
+    /**
+     * @return {@link #failOnMissingWebXml}
+     */
+    public boolean isFailOnMissingWebXml()
+    {
+        return failOnMissingWebXml;
+    }
+
+    /**
+     * @param failOnMissingWebXml {@link #failOnMissingWebXml}
+     */
+    public void setFailOnMissingWebXml( boolean failOnMissingWebXml )
+    {
+        this.failOnMissingWebXml = failOnMissingWebXml;
+    }
+
+    public boolean isSkip()
+    {
+        return skip;
+    }
+}
diff --git a/Java/maven-war-plugin-WarMojo_349/metadata.json b/Java/maven-war-plugin-WarMojo_349/metadata.json
new file mode 100644
index 000000000..1f0939743
--- /dev/null
+++ b/Java/maven-war-plugin-WarMojo_349/metadata.json
@@ -0,0 +1,21 @@
+{
+  "language": "java",
+  "id": "maven-war-plugin-WarMojo_349",
+  "buggyPath": ".",
+  "referencePath": null,
+  "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+  "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+  "categories": [
+    "safety",
+    "npe"
+  ],
+  "npe": {
+    "filepath": "src/main/java/org/apache/maven/plugins/war/WarMojo.java",
+    "line": 363,
+    "npe_method": "getTargetFile",
+    "deref_field": "classifier",
+    "npe_class": "WarMojo",
+    "repo": "maven-war-plugin",
+    "bug_id": "WarMojo_349"
+  }
+}
diff --git a/Java/maven-war-plugin-WarMojo_349/npe.json b/Java/maven-war-plugin-WarMojo_349/npe.json
new file mode 100644
index 000000000..4073aec0b
--- /dev/null
+++ b/Java/maven-war-plugin-WarMojo_349/npe.json
@@ -0,0 +1,7 @@
+{
+    "filepath": "src/main/java/org/apache/maven/plugins/war/WarMojo.java",
+    "line": 363,
+    "npe_method": "getTargetFile",
+    "deref_field": "classifier",
+    "npe_class": "WarMojo"
+}
\ No newline at end of file
diff --git a/Java/maven-war-plugin-WarProjectPackagingTask_327/Dockerfile b/Java/maven-war-plugin-WarProjectPackagingTask_327/Dockerfile
new file mode 100644
index 000000000..34955205a
--- /dev/null
+++ b/Java/maven-war-plugin-WarProjectPackagingTask_327/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:maven-war-plugin
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+    && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+    && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+    && mv /tmp/buggy.java $BUGGY_PATH \
+    && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/maven-war-plugin-WarProjectPackagingTask_327/buggy.java b/Java/maven-war-plugin-WarProjectPackagingTask_327/buggy.java
new file mode 100644
index 000000000..9edee00b6
--- /dev/null
+++ b/Java/maven-war-plugin-WarProjectPackagingTask_327/buggy.java
@@ -0,0 +1,380 @@
+package org.apache.maven.plugins.war.packaging;
+
+/*
+ * 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.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Objects;
+
+import org.apache.maven.model.Resource;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.war.Overlay;
+import org.apache.maven.plugins.war.util.PathSet;
+import org.apache.maven.shared.filtering.MavenFilteringException;
+import org.codehaus.plexus.util.DirectoryScanner;
+import org.codehaus.plexus.util.StringUtils;
+
+/**
+ * Handles the project own resources, that is: 
+ * <ul>
+ * <li>The list of web resources, if any</li>
+ * <li>The content of the webapp directory if it exists</li>
+ * <li>The custom deployment descriptor(s), if any</li>
+ * <li>The content of the classes directory if it exists</li>
+ * <li>The dependencies of the project</li>
+ * </ul>
+ *
+ * @author Stephane Nicoll
+ */
+public class WarProjectPackagingTask
+    extends AbstractWarPackagingTask
+{
+    private final Resource[] webResources;
+
+    private final File webXml;
+
+    private final File containerConfigXML;
+
+    private final String id;
+
+    private Overlay currentProjectOverlay;
+
+    /**
+     * @param webResources {@link #webResources}
+     * @param webXml {@link #webXml}
+     * @param containerConfigXml {@link #containerConfigXML}
+     * @param currentProjectOverlay {@link #currentProjectOverlay}
+     */
+    public WarProjectPackagingTask( Resource[] webResources, File webXml, File containerConfigXml,
+                                    Overlay currentProjectOverlay )
+    {
+        if ( webResources != null )
+        {
+            this.webResources = webResources;
+        }
+        else
+        {
+            this.webResources = new Resource[0];
+        }
+        this.webXml = webXml;
+        this.containerConfigXML = containerConfigXml;
+        this.currentProjectOverlay = currentProjectOverlay;
+        this.id = currentProjectOverlay.getId();
+    }
+
+    @Override
+    public void performPackaging( WarPackagingContext context )
+        throws MojoExecutionException, MojoFailureException
+    {
+        context.getLog().info( "Processing war project" );
+
+        // Prepare the INF directories
+        File webinfDir = new File( context.getWebappDirectory(), WEB_INF_PATH );
+        webinfDir.mkdirs();
+        File metainfDir = new File( context.getWebappDirectory(), META_INF_PATH );
+        metainfDir.mkdirs();
+
+        handleWebResources( context );
+
+        handleWebAppSourceDirectory( context );
+
+        // Debug mode: dump the path set for the current build
+        PathSet pathSet = context.getWebappStructure().getStructure( "currentBuild" );
+        context.getLog().debug( "Dump of the current build pathSet content -->" );
+        for ( String path : pathSet )
+        {
+            context.getLog().debug( path );
+        }
+        context.getLog().debug( "-- end of dump --" );
+
+        handleDeploymentDescriptors( context, webinfDir, metainfDir, context.isFailOnMissingWebXml() );
+
+        handleClassesDirectory( context );
+
+        handleArtifacts( context );
+
+        if ( !context.getWebappDirectory().mkdirs() )
+        {
+            context.deleteOutdatedResources();
+        }
+    }
+
+    /**
+     * Handles the web resources.
+     *
+     * @param context the packaging context
+     * @throws MojoExecutionException if a resource could not be copied
+     */
+    protected void handleWebResources( WarPackagingContext context )
+        throws MojoExecutionException
+    {
+        for ( Resource resource : webResources )
+        {
+
+            // MWAR-246
+            if ( resource.getDirectory() == null )
+            {
+                throw new MojoExecutionException( "The <directory> tag is missing from the <resource> tag." );
+            }
+
+            if ( !( new File( resource.getDirectory() ) ).isAbsolute() )
+            {
+                resource.setDirectory( context.getProject().getBasedir() + File.separator + resource.getDirectory() );
+            }
+
+            // Make sure that the resource directory is not the same as the webappDirectory
+            if ( !resource.getDirectory().equals( context.getWebappDirectory().getPath() ) )
+            {
+
+                try
+                {
+                    copyResources( context, resource );
+                }
+                catch ( IOException e )
+                {
+                    throw new MojoExecutionException( "Could not copy resource [" + resource.getDirectory() + "]", e );
+                }
+            }
+        }
+    }
+
+    /**
+     * Handles the webapp sources.
+     *
+     * @param context the packaging context
+     * @throws MojoExecutionException if the sources could not be copied
+     */
+    protected void handleWebAppSourceDirectory( WarPackagingContext context )
+        throws MojoExecutionException
+    {
+        // CHECKSTYLE_OFF: LineLength
+        if ( !context.getWebappSourceDirectory().exists() )
+        {
+            context.getLog().debug( "webapp sources directory does not exist - skipping." );
+        }
+        else if ( !context.getWebappSourceDirectory().getAbsolutePath().equals( context.getWebappDirectory().getPath() ) )
+        {
+            context.getLog().info( "Copying webapp resources [" + context.getWebappSourceDirectory() + "]" );
+            final PathSet sources =
+                getFilesToIncludes( context.getWebappSourceDirectory(), context.getWebappSourceIncludes(),
+                                    context.getWebappSourceExcludes(), context.isWebappSourceIncludeEmptyDirectories() );
+
+            try
+            {
+                copyFiles( id, context, context.getWebappSourceDirectory(), sources, false );
+            }
+            catch ( IOException e )
+            {
+                throw new MojoExecutionException( "Could not copy webapp sources ["
+                    + context.getWebappDirectory().getAbsolutePath() + "]", e );
+            }
+        }
+        // CHECKSTYLE_ON: LineLength
+    }
+
+    /**
+     * Handles the webapp artifacts.
+     *
+     * @param context the packaging context
+     * @throws MojoExecutionException if the artifacts could not be packaged
+     */
+    protected void handleArtifacts( WarPackagingContext context )
+        throws MojoExecutionException
+    {
+        ArtifactsPackagingTask task =
+            new ArtifactsPackagingTask( context.getProject().getArtifacts(), currentProjectOverlay );
+        task.performPackaging( context );
+    }
+
+    /**
+     * Handles the webapp classes.
+     *
+     * @param context the packaging context
+     * @throws MojoExecutionException if the classes could not be packaged
+     */
+    protected void handleClassesDirectory( WarPackagingContext context )
+        throws MojoExecutionException
+    {
+        ClassesPackagingTask task = new ClassesPackagingTask( currentProjectOverlay );
+        task.performPackaging( context );
+    }
+
+    /**
+     * Handles the deployment descriptors, if specified. Note that the behavior here is slightly different since the
+     * customized entry always win, even if an overlay has already packaged a web.xml previously.
+     *
+     * @param context the packaging context
+     * @param webinfDir the web-inf directory
+     * @param metainfDir the meta-inf directory
+     * @param failOnMissingWebXml if build should fail if web.xml is not found
+     * @throws MojoFailureException if the web.xml is specified but does not exist and failOnMissingWebXml is true
+     * @throws MojoExecutionException if an error occurred while copying the descriptors
+     */
+    protected void handleDeploymentDescriptors( WarPackagingContext context, File webinfDir, File metainfDir,
+                                                Boolean failOnMissingWebXml )
+        throws MojoFailureException, MojoExecutionException
+    {
+        try
+        {
+            if ( webXml != null && StringUtils.isNotEmpty( webXml.getName() ) )
+            {
+                if ( !webXml.exists()
+                        && ( failOnMissingWebXml == null || Boolean.TRUE.equals( failOnMissingWebXml ) ) )
+                {
+                    throw new MojoFailureException( "The specified web.xml file '" + webXml + "' does not exist" );
+                }
+
+                // Making sure that it won't get overlayed
+                context.getWebappStructure().registerFileForced( id, WEB_INF_PATH + "/web.xml" );
+
+                if ( context.isFilteringDeploymentDescriptors() )
+                {
+                    context.getMavenFileFilter().copyFile( webXml, new File( webinfDir, "web.xml" ), true,
+                                                           context.getFilterWrappers(), getEncoding( webXml ) );
+                }
+                else
+                {
+                    copyFile( context, webXml, new File( webinfDir, "web.xml" ), "WEB-INF/web.xml", true );
+                }
+            }
+            else
+            {
+                // the webXml can be the default one
+                File defaultWebXml = new File( context.getWebappSourceDirectory(), WEB_INF_PATH + "/web.xml" );
+                // if exists we can filter it
+                if ( defaultWebXml.exists() && context.isFilteringDeploymentDescriptors() )
+                {
+                    context.getWebappStructure().registerFile( id, WEB_INF_PATH + "/web.xml" );
+                    context.getMavenFileFilter().copyFile( defaultWebXml, new File( webinfDir, "web.xml" ), true,
+                                                           context.getFilterWrappers(), getEncoding( defaultWebXml ) );
+                }
+            }
+
+            if ( containerConfigXML != null && StringUtils.isNotEmpty( containerConfigXML.getName() ) )
+            {
+                String xmlFileName = containerConfigXML.getName();
+
+                context.getWebappStructure().registerFileForced( id, META_INF_PATH + "/" + xmlFileName );
+
+                if ( context.isFilteringDeploymentDescriptors() )
+                {
+                    context.getMavenFileFilter().copyFile( containerConfigXML, new File( metainfDir, xmlFileName ),
+                                                           true, context.getFilterWrappers(),
+                                                           getEncoding( containerConfigXML ) );
+                }
+                else
+                {
+                    copyFile( context, containerConfigXML, new File( metainfDir, xmlFileName ), "META-INF/"
+                        + xmlFileName, true );
+                }
+            }
+        }
+        catch ( IOException e )
+        {
+            if ( failOnMissingWebXml == null || Boolean.TRUE.equals( failOnMissingWebXml ) )
+            {
+                throw new MojoExecutionException( "Failed to copy deployment descriptor", e );
+            }
+        }
+        catch ( MavenFilteringException e )
+        {
+            throw new MojoExecutionException( "Failed to copy deployment descriptor", e );
+        }
+    }
+
+    /**
+     * Copies webapp webResources from the specified directory.
+     *
+     * @param context the WAR packaging context to use
+     * @param resource the resource to copy
+     * @throws IOException if an error occurred while copying the resources
+     * @throws MojoExecutionException if an error occurred while retrieving the filter properties
+     */
+/**
+ * Copies webapp webResources from the specified directory.
+ *
+ * @param context
+ * 		the WAR packaging context to use
+ * @param resource
+ * 		the resource to copy
+ * @throws IOException
+ * 		if an error occurred while copying the resources
+ * @throws MojoExecutionException
+ * 		if an error occurred while retrieving the filter properties
+ */
+public void copyResources(org.apache.maven.plugins.war.packaging.WarPackagingContext context, org.apache.maven.model.Resource resource) throws java.io.IOException, org.apache.maven.plugin.MojoExecutionException {
+    if (!context.getWebappDirectory().exists()) {
+        context.getLog().warn(((("Not copying webapp webResources [" + resource.getDirectory()) + "]: webapp directory [") + context.getWebappDirectory().getAbsolutePath()) + "] does not exist!");
+    }
+    context.getLog().info(((("Copying webapp webResources [" + resource.getDirectory()) + "] to [") + context.getWebappDirectory().getAbsolutePath()) + "]");
+    java.lang.String[] fileNames = getFilesToCopy(resource);
+    for (java.lang.String fileName : fileNames) {
+        java.lang.String targetFileName = fileName;
+        {
+            // TODO make sure this thing is 100% safe
+            // MWAR-129 if targetPath is only a dot <targetPath>.</targetPath> or ./
+            // and the Resource is in a part of the warSourceDirectory the file from sources will override this
+            // that's we don't have to add the targetPath yep not nice but works
+            if ((!java.util.Objects.equals(".", /* NPEX_NULL_EXP */
+            resource.getTargetPath())) && (!java.util.Objects.equals("./", resource.getTargetPath()))) {
+                targetFileName = (resource.getTargetPath() + java.io.File.separator) + targetFileName;
+            }
+        }
+        if (resource.isFiltering() && (!context.isNonFilteredExtension(fileName))) {
+            copyFilteredFile(id, context, new java.io.File(resource.getDirectory(), fileName), targetFileName);
+        } else {
+            copyFile(id, context, new java.io.File(resource.getDirectory(), fileName), targetFileName);
+        }
+    }
+}
+
+    /**
+     * Returns a list of filenames that should be copied over to the destination directory.
+     *
+     * @param resource the resource to be scanned
+     * @return the array of filenames, relative to the sourceDir
+     */
+    private String[] getFilesToCopy( Resource resource )
+    {
+        // CHECKSTYLE_OFF: LineLength
+        DirectoryScanner scanner = new DirectoryScanner();
+        scanner.setBasedir( resource.getDirectory() );
+        if ( resource.getIncludes() != null && !resource.getIncludes().isEmpty() )
+        {
+            scanner.setIncludes( resource.getIncludes().toArray( new String[resource.getIncludes().size()] ) );
+        }
+        else
+        {
+            scanner.setIncludes( DEFAULT_INCLUDES );
+        }
+        if ( resource.getExcludes() != null && !resource.getExcludes().isEmpty() )
+        {
+            scanner.setExcludes( resource.getExcludes().toArray( new String[resource.getExcludes().size()] ) );
+        }
+
+        scanner.addDefaultExcludes();
+
+        scanner.scan();
+
+        return scanner.getIncludedFiles();
+        // CHECKSTYLE_ON: LineLength
+    }
+}
diff --git a/Java/maven-war-plugin-WarProjectPackagingTask_327/metadata.json b/Java/maven-war-plugin-WarProjectPackagingTask_327/metadata.json
new file mode 100644
index 000000000..075a965fe
--- /dev/null
+++ b/Java/maven-war-plugin-WarProjectPackagingTask_327/metadata.json
@@ -0,0 +1,21 @@
+{
+  "language": "java",
+  "id": "maven-war-plugin-WarProjectPackagingTask_327",
+  "buggyPath": ".",
+  "referencePath": null,
+  "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+  "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+  "categories": [
+    "safety",
+    "npe"
+  ],
+  "npe": {
+    "filepath": "src/main/java/org/apache/maven/plugins/war/packaging/WarProjectPackagingTask.java",
+    "line": 337,
+    "npe_method": "copyResources",
+    "deref_field": "getTargetPath",
+    "npe_class": "WarProjectPackagingTask",
+    "repo": "maven-war-plugin",
+    "bug_id": "WarProjectPackagingTask_327"
+  }
+}
diff --git a/Java/maven-war-plugin-WarProjectPackagingTask_327/npe.json b/Java/maven-war-plugin-WarProjectPackagingTask_327/npe.json
new file mode 100644
index 000000000..031939565
--- /dev/null
+++ b/Java/maven-war-plugin-WarProjectPackagingTask_327/npe.json
@@ -0,0 +1,7 @@
+{
+    "filepath": "src/main/java/org/apache/maven/plugins/war/packaging/WarProjectPackagingTask.java",
+    "line": 337,
+    "npe_method": "copyResources",
+    "deref_field": "getTargetPath",
+    "npe_class": "WarProjectPackagingTask"
+}
\ No newline at end of file
diff --git a/Java/tiles-BaseLocaleUrlDefinitionDAO_161/Dockerfile b/Java/tiles-BaseLocaleUrlDefinitionDAO_161/Dockerfile
new file mode 100644
index 000000000..6bd79b5d5
--- /dev/null
+++ b/Java/tiles-BaseLocaleUrlDefinitionDAO_161/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:tiles
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+    && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+    && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+    && mv /tmp/buggy.java $BUGGY_PATH \
+    && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/tiles-BaseLocaleUrlDefinitionDAO_161/buggy.java b/Java/tiles-BaseLocaleUrlDefinitionDAO_161/buggy.java
new file mode 100644
index 000000000..f3047efb9
--- /dev/null
+++ b/Java/tiles-BaseLocaleUrlDefinitionDAO_161/buggy.java
@@ -0,0 +1,174 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition.dao;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.tiles.Definition;
+import org.apache.tiles.definition.DefinitionsFactoryException;
+import org.apache.tiles.definition.DefinitionsReader;
+import org.apache.tiles.definition.RefreshMonitor;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.ApplicationResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Base abstract class for a DAO that is based on URLs and locale as a
+ * customization key.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.1.0
+ */
+public abstract class BaseLocaleUrlDefinitionDAO implements
+        DefinitionDAO<Locale>, RefreshMonitor {
+
+    /**
+     * The logging object.
+     */
+    private final Logger log = LoggerFactory
+            .getLogger(BaseLocaleUrlDefinitionDAO.class);
+
+    /**
+     * Contains the URL objects identifying where configuration data is found.
+     *
+     * @since 2.1.0
+     */
+    protected List<ApplicationResource> sources;
+
+    /**
+     * Contains the dates that the URL sources were last modified.
+     *
+     * @since 2.1.0
+     */
+    protected Map<String, Long> lastModifiedDates;
+
+    /**
+     * Reader used to get definitions from the sources.
+     *
+     * @since 2.1.0
+     */
+    protected DefinitionsReader reader;
+
+    /**
+     * ApplicationContext to locate the source files.
+     *
+     * @since 3.0.0
+     */
+    protected ApplicationContext applicationContext;
+
+    /**
+     * Constructor.
+     */
+    public BaseLocaleUrlDefinitionDAO(ApplicationContext applicationContext) {
+        this.applicationContext = applicationContext;
+        lastModifiedDates = new HashMap<String, Long>();
+    }
+
+    public void setSources(List<ApplicationResource> sources) {
+        // filter out any sources that are already localized
+        ArrayList<ApplicationResource> defaultSources = new ArrayList<ApplicationResource>();
+        for(ApplicationResource source: sources) {
+            if(Locale.ROOT.equals(source.getLocale())) {
+                defaultSources.add(source);
+            }
+        }
+        this.sources = defaultSources;
+    }
+
+    public void setReader(DefinitionsReader reader) {
+        this.reader = reader;
+    }
+
+    /** {@inheritDoc} */
+    public boolean refreshRequired() {
+        boolean status = false;
+
+        Set<String> paths = lastModifiedDates.keySet();
+
+        try {
+            for (String path : paths) {
+                Long lastModifiedDate = lastModifiedDates.get(path);
+                ApplicationResource resource = applicationContext.getResource(path);
+                long newModDate = resource.getLastModified();
+                if (newModDate != lastModifiedDate) {
+                    status = true;
+                    break;
+                }
+            }
+        } catch (IOException e) {
+            log.warn("Exception while monitoring update times.", e);
+            return true;
+        }
+        return status;
+    }
+
+    /**
+     * Loads definitions from an URL without loading from "parent" URLs.
+     *
+     * @param resource The URL to read.
+     * @return The definition map that has been read.
+     */
+/**
+ * Loads definitions from an URL without loading from "parent" URLs.
+ *
+ * @param resource
+ * 		The URL to read.
+ * @return The definition map that has been read.
+ */
+protected java.util.Map<java.lang.String, org.apache.tiles.Definition> loadDefinitionsFromResource(org.apache.tiles.request.ApplicationResource resource) {
+    java.util.Map<java.lang.String, org.apache.tiles.Definition> defsMap = null;
+    java.io.InputStream stream = null;
+    try {
+        lastModifiedDates.put(resource.getLocalePath(), resource.getLastModified());
+        // Definition must be collected, starting from the base
+        // source up to the last localized file.
+        stream = resource.getInputStream();
+        defsMap = reader.read(stream);
+    } catch (java.io.FileNotFoundException e) {
+        // File not found. continue.
+        if (log.isDebugEnabled()) {
+            log.debug(("File " + resource.toString()) + " not found, continue");
+        }
+    } catch (java.io.IOException e) {
+        throw new org.apache.tiles.definition.DefinitionsFactoryException("I/O error processing configuration.", e);
+    } finally {
+        try {
+            {
+                /* NPEX_NULL_EXP */
+                stream.close();
+            }
+        } catch (java.io.IOException e) {
+            throw new org.apache.tiles.definition.DefinitionsFactoryException("I/O error closing " + resource.toString(), e);
+        }
+    }
+    return defsMap;
+}
+}
diff --git a/Java/tiles-BaseLocaleUrlDefinitionDAO_161/metadata.json b/Java/tiles-BaseLocaleUrlDefinitionDAO_161/metadata.json
new file mode 100644
index 000000000..11eb4aed9
--- /dev/null
+++ b/Java/tiles-BaseLocaleUrlDefinitionDAO_161/metadata.json
@@ -0,0 +1,21 @@
+{
+  "language": "java",
+  "id": "tiles-BaseLocaleUrlDefinitionDAO_161",
+  "buggyPath": ".",
+  "referencePath": null,
+  "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+  "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+  "categories": [
+    "safety",
+    "npe"
+  ],
+  "npe": {
+    "filepath": "tiles-core/src/main/java/org/apache/tiles/definition/dao/BaseLocaleUrlDefinitionDAO.java",
+    "line": 166,
+    "npe_method": "loadDefinitionsFromResource",
+    "deref_field": "stream",
+    "npe_class": "BaseLocaleUrlDefinitionDAO",
+    "repo": "tiles",
+    "bug_id": "BaseLocaleUrlDefinitionDAO_161"
+  }
+}
diff --git a/Java/tiles-BaseLocaleUrlDefinitionDAO_161/npe.json b/Java/tiles-BaseLocaleUrlDefinitionDAO_161/npe.json
new file mode 100644
index 000000000..7ed8b56c2
--- /dev/null
+++ b/Java/tiles-BaseLocaleUrlDefinitionDAO_161/npe.json
@@ -0,0 +1,7 @@
+{
+    "filepath": "tiles-core/src/main/java/org/apache/tiles/definition/dao/BaseLocaleUrlDefinitionDAO.java",
+    "line": 166,
+    "npe_method": "loadDefinitionsFromResource",
+    "deref_field": "stream",
+    "npe_class": "BaseLocaleUrlDefinitionDAO"
+}
\ No newline at end of file
diff --git a/Java/tiles-CachingLocaleUrlDefinitionDAO_231/Dockerfile b/Java/tiles-CachingLocaleUrlDefinitionDAO_231/Dockerfile
new file mode 100644
index 000000000..6bd79b5d5
--- /dev/null
+++ b/Java/tiles-CachingLocaleUrlDefinitionDAO_231/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:tiles
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+    && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+    && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+    && mv /tmp/buggy.java $BUGGY_PATH \
+    && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/tiles-CachingLocaleUrlDefinitionDAO_231/buggy.java b/Java/tiles-CachingLocaleUrlDefinitionDAO_231/buggy.java
new file mode 100644
index 000000000..e947c298d
--- /dev/null
+++ b/Java/tiles-CachingLocaleUrlDefinitionDAO_231/buggy.java
@@ -0,0 +1,279 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition.dao;
+
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.tiles.Definition;
+import org.apache.tiles.definition.pattern.PatternDefinitionResolver;
+import org.apache.tiles.definition.pattern.PatternDefinitionResolverAware;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.ApplicationResource;
+import org.apache.tiles.request.locale.LocaleUtil;
+
+/**
+ * <p>
+ * A definitions DAO (loading URLs and using Locale as a customization key) that
+ * caches definitions that have been loaded in a raw way (i.e. with inheritance
+ * that is not resolved).
+ * </p>
+ * <p>
+ * It can check if the URLs change, but by default this feature is turned off.
+ * </p>
+ *
+ * @version $Rev$ $Date$
+ * @since 2.1.0
+ */
+public class CachingLocaleUrlDefinitionDAO extends BaseLocaleUrlDefinitionDAO
+        implements PatternDefinitionResolverAware<Locale> {
+
+    /**
+     * Initialization parameter to set whether we want to refresh URLs when they
+     * change.
+     *
+     * @since 2.1.0
+     */
+    public static final String CHECK_REFRESH_INIT_PARAMETER =
+        "org.apache.tiles.definition.dao.LocaleUrlDefinitionDAO.CHECK_REFRESH";
+
+    /**
+     * The locale-specific set of definitions objects.
+     *
+     * @since 2.1.0
+     */
+    protected Map<Locale, Map<String, Definition>> locale2definitionMap;
+
+    /**
+     * Flag that, when <code>true</code>, enables automatic checking of URLs
+     * changing.
+     *
+     * @since 2.1.0
+     */
+    protected boolean checkRefresh = false;
+
+    /**
+     * Resolves definitions using patterns.
+     *
+     * @since 2.2.0
+     */
+    protected PatternDefinitionResolver<Locale> definitionResolver;
+
+    /**
+     * Constructor.
+     *
+     * @since 2.1.0
+     */
+    public CachingLocaleUrlDefinitionDAO(ApplicationContext applicationContext) {
+        super(applicationContext);
+        locale2definitionMap = new HashMap<Locale, Map<String, Definition>>();
+    }
+
+    /** {@inheritDoc} */
+    public void setPatternDefinitionResolver(
+            PatternDefinitionResolver<Locale> definitionResolver) {
+        this.definitionResolver = definitionResolver;
+    }
+
+    /** {@inheritDoc} */
+    public Definition getDefinition(String name, Locale customizationKey) {
+        Definition retValue = null;
+        if (customizationKey == null) {
+            customizationKey = Locale.ROOT;
+        }
+        Map<String, Definition> definitions = getDefinitions(customizationKey);
+        if (definitions != null) {
+            retValue = definitions.get(name);
+
+            if (retValue == null) {
+                retValue = getDefinitionFromResolver(name, customizationKey);
+
+                if (retValue != null) {
+                    synchronized (definitions) {
+                        definitions.put(name, retValue);
+                    }
+                }
+            }
+        }
+
+        return retValue;
+    }
+
+    /** {@inheritDoc} */
+    public Map<String, Definition> getDefinitions(Locale customizationKey) {
+        if (customizationKey == null) {
+            customizationKey = Locale.ROOT;
+        }
+        Map<String, Definition> retValue = locale2definitionMap
+                .get(customizationKey);
+        if (retValue == null || (checkRefresh && refreshRequired())) {
+            retValue = checkAndloadDefinitions(customizationKey);
+        }
+        return retValue;
+    }
+
+    /**
+     * Sets the flag to check source refresh. If not called, the default is
+     * <code>false</code>.
+     *
+     * @param checkRefresh When <code>true</code>, enables automatic checking
+     * of sources changing.
+     * @since 2.1.0
+     */
+    public void setCheckRefresh(boolean checkRefresh) {
+        this.checkRefresh = checkRefresh;
+    }
+
+    /**
+     * Returns a definition from the definition resolver.
+     *
+     * @param name The name of the definition.
+     * @param customizationKey The customization key to use.
+     * @return The resolved definition.
+     */
+    protected Definition getDefinitionFromResolver(String name,
+            Locale customizationKey) {
+        return definitionResolver.resolveDefinition(name,
+                customizationKey);
+    }
+
+    /**
+     * Checks if sources have changed. If yes, it clears the cache. Then continues
+     * loading definitions.
+     *
+     * @param customizationKey The locale to use when loading sources.
+     * @return The loaded definitions.
+     * @since 2.1.0
+     */
+    protected synchronized Map<String, Definition> checkAndloadDefinitions(Locale customizationKey) {
+        Map<String, Definition> existingDefinitions = locale2definitionMap.get(customizationKey);
+        boolean definitionsAlreadyLoaded = existingDefinitions != null;
+        if (definitionsAlreadyLoaded) {
+            return existingDefinitions;
+        }
+        if (checkRefresh && refreshRequired()) {
+            locale2definitionMap.clear();
+            definitionResolver.clearPatternPaths(customizationKey);
+        }
+        loadDefinitions(customizationKey);
+        return locale2definitionMap.get(customizationKey);
+    }
+
+    /**
+     * Tries to load definitions if necessary.
+     *
+     * @param customizationKey The locale to use when loading sources.
+     * @return The loaded definitions.
+     * @since 2.1.0
+     */
+    protected Map<String, Definition> loadDefinitions(Locale customizationKey) {
+        Map<String, Definition> localeDefsMap = locale2definitionMap
+                .get(customizationKey);
+        if (localeDefsMap != null) {
+            return localeDefsMap;
+        }
+
+        return loadDefinitionsFromResources(customizationKey);
+    }
+
+    /**
+     * Loads definitions from the sources.
+     *
+     * @param customizationKey The locale to use when loading Resources.
+     * @return The loaded definitions.
+     * @since 2.1.0
+     */
+    protected Map<String, Definition> loadDefinitionsFromResources(Locale customizationKey) {
+        Map<String, Definition> localeDefsMap = loadRawDefinitionsFromResources(customizationKey);
+        Map<String, Definition> defsMap = definitionResolver
+                .storeDefinitionPatterns(copyDefinitionMap(localeDefsMap),
+                        customizationKey);
+        locale2definitionMap.put(customizationKey, defsMap);
+        return localeDefsMap;
+    }
+
+    /**
+     * Loads the raw definitions from the sources associated with a locale.
+     *
+     * @param customizationKey The locale to use when loading Resources.
+     * @return The loaded definitions.
+     * @since 2.1.3
+     */
+/**
+ * Loads the raw definitions from the sources associated with a locale.
+ *
+ * @param customizationKey
+ * 		The locale to use when loading Resources.
+ * @return The loaded definitions.
+ * @since 2.1.3
+ */
+protected java.util.Map<java.lang.String, org.apache.tiles.Definition> loadRawDefinitionsFromResources(java.util.Locale customizationKey) {
+    java.util.Map<java.lang.String, org.apache.tiles.Definition> localeDefsMap;
+    java.util.Locale parentLocale = org.apache.tiles.request.locale.LocaleUtil.getParentLocale(customizationKey);
+    localeDefsMap = new java.util.LinkedHashMap<java.lang.String, org.apache.tiles.Definition>();
+    {
+        java.util.Map<java.lang.String, org.apache.tiles.Definition> parentDefs = loadRawDefinitionsFromResources(parentLocale);
+        {
+            localeDefsMap.putAll(/* NPEX_NULL_EXP */
+            parentDefs);
+        }
+    }
+    // For each source, the resource must be loaded.
+    for (org.apache.tiles.request.ApplicationResource resource : sources) {
+        org.apache.tiles.request.ApplicationResource newResource = applicationContext.getResource(resource, customizationKey);
+        if (newResource != null) {
+            java.util.Map<java.lang.String, org.apache.tiles.Definition> defsMap = loadDefinitionsFromResource(newResource);
+            if (defsMap != null) {
+                localeDefsMap.putAll(defsMap);
+            }
+        }
+    }
+    return localeDefsMap;
+}
+
+    /**
+     * Loads parent definitions, i.e. definitions mapped to a parent locale.
+     *
+     * @param parentLocale The locale to use when loading URLs.
+     * @return The loaded parent definitions.
+     * @since 2.1.0
+     */
+    protected Map<String, Definition> loadParentDefinitions(Locale parentLocale) {
+        return loadDefinitions(parentLocale);
+    }
+
+    /**
+     * Copies the definition map to be passed to a higher level of customization
+     * key.
+     *
+     * @param localeDefsMap The map of definition to be copied.
+     * @return The copy of the definition map. This particular implementation
+     * return the <code>localeDefsMap</code> itself.
+     * @since 2.1.4
+     */
+    protected Map<String, Definition> copyDefinitionMap(
+            Map<String, Definition> localeDefsMap) {
+        return localeDefsMap;
+    }
+}
diff --git a/Java/tiles-CachingLocaleUrlDefinitionDAO_231/metadata.json b/Java/tiles-CachingLocaleUrlDefinitionDAO_231/metadata.json
new file mode 100644
index 000000000..dcbcfc6e8
--- /dev/null
+++ b/Java/tiles-CachingLocaleUrlDefinitionDAO_231/metadata.json
@@ -0,0 +1,21 @@
+{
+  "language": "java",
+  "id": "tiles-CachingLocaleUrlDefinitionDAO_231",
+  "buggyPath": ".",
+  "referencePath": null,
+  "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+  "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+  "categories": [
+    "safety",
+    "npe"
+  ],
+  "npe": {
+    "filepath": "tiles-core/src/main/java/org/apache/tiles/definition/dao/CachingLocaleUrlDefinitionDAO.java",
+    "line": 239,
+    "npe_method": "loadRawDefinitionsFromResources",
+    "deref_field": "parentDefs",
+    "npe_class": "CachingLocaleUrlDefinitionDAO",
+    "repo": "tiles",
+    "bug_id": "CachingLocaleUrlDefinitionDAO_231"
+  }
+}
diff --git a/Java/tiles-CachingLocaleUrlDefinitionDAO_231/npe.json b/Java/tiles-CachingLocaleUrlDefinitionDAO_231/npe.json
new file mode 100644
index 000000000..bc47b772b
--- /dev/null
+++ b/Java/tiles-CachingLocaleUrlDefinitionDAO_231/npe.json
@@ -0,0 +1,7 @@
+{
+    "filepath": "tiles-core/src/main/java/org/apache/tiles/definition/dao/CachingLocaleUrlDefinitionDAO.java",
+    "line": 239,
+    "npe_method": "loadRawDefinitionsFromResources",
+    "deref_field": "parentDefs",
+    "npe_class": "CachingLocaleUrlDefinitionDAO"
+}
\ No newline at end of file
diff --git a/Java/tiles-CachingLocaleUrlDefinitionDAO_238/Dockerfile b/Java/tiles-CachingLocaleUrlDefinitionDAO_238/Dockerfile
new file mode 100644
index 000000000..6bd79b5d5
--- /dev/null
+++ b/Java/tiles-CachingLocaleUrlDefinitionDAO_238/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:tiles
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+    && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+    && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+    && mv /tmp/buggy.java $BUGGY_PATH \
+    && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/tiles-CachingLocaleUrlDefinitionDAO_238/buggy.java b/Java/tiles-CachingLocaleUrlDefinitionDAO_238/buggy.java
new file mode 100644
index 000000000..b2645269c
--- /dev/null
+++ b/Java/tiles-CachingLocaleUrlDefinitionDAO_238/buggy.java
@@ -0,0 +1,279 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition.dao;
+
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.tiles.Definition;
+import org.apache.tiles.definition.pattern.PatternDefinitionResolver;
+import org.apache.tiles.definition.pattern.PatternDefinitionResolverAware;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.ApplicationResource;
+import org.apache.tiles.request.locale.LocaleUtil;
+
+/**
+ * <p>
+ * A definitions DAO (loading URLs and using Locale as a customization key) that
+ * caches definitions that have been loaded in a raw way (i.e. with inheritance
+ * that is not resolved).
+ * </p>
+ * <p>
+ * It can check if the URLs change, but by default this feature is turned off.
+ * </p>
+ *
+ * @version $Rev$ $Date$
+ * @since 2.1.0
+ */
+public class CachingLocaleUrlDefinitionDAO extends BaseLocaleUrlDefinitionDAO
+        implements PatternDefinitionResolverAware<Locale> {
+
+    /**
+     * Initialization parameter to set whether we want to refresh URLs when they
+     * change.
+     *
+     * @since 2.1.0
+     */
+    public static final String CHECK_REFRESH_INIT_PARAMETER =
+        "org.apache.tiles.definition.dao.LocaleUrlDefinitionDAO.CHECK_REFRESH";
+
+    /**
+     * The locale-specific set of definitions objects.
+     *
+     * @since 2.1.0
+     */
+    protected Map<Locale, Map<String, Definition>> locale2definitionMap;
+
+    /**
+     * Flag that, when <code>true</code>, enables automatic checking of URLs
+     * changing.
+     *
+     * @since 2.1.0
+     */
+    protected boolean checkRefresh = false;
+
+    /**
+     * Resolves definitions using patterns.
+     *
+     * @since 2.2.0
+     */
+    protected PatternDefinitionResolver<Locale> definitionResolver;
+
+    /**
+     * Constructor.
+     *
+     * @since 2.1.0
+     */
+    public CachingLocaleUrlDefinitionDAO(ApplicationContext applicationContext) {
+        super(applicationContext);
+        locale2definitionMap = new HashMap<Locale, Map<String, Definition>>();
+    }
+
+    /** {@inheritDoc} */
+    public void setPatternDefinitionResolver(
+            PatternDefinitionResolver<Locale> definitionResolver) {
+        this.definitionResolver = definitionResolver;
+    }
+
+    /** {@inheritDoc} */
+    public Definition getDefinition(String name, Locale customizationKey) {
+        Definition retValue = null;
+        if (customizationKey == null) {
+            customizationKey = Locale.ROOT;
+        }
+        Map<String, Definition> definitions = getDefinitions(customizationKey);
+        if (definitions != null) {
+            retValue = definitions.get(name);
+
+            if (retValue == null) {
+                retValue = getDefinitionFromResolver(name, customizationKey);
+
+                if (retValue != null) {
+                    synchronized (definitions) {
+                        definitions.put(name, retValue);
+                    }
+                }
+            }
+        }
+
+        return retValue;
+    }
+
+    /** {@inheritDoc} */
+    public Map<String, Definition> getDefinitions(Locale customizationKey) {
+        if (customizationKey == null) {
+            customizationKey = Locale.ROOT;
+        }
+        Map<String, Definition> retValue = locale2definitionMap
+                .get(customizationKey);
+        if (retValue == null || (checkRefresh && refreshRequired())) {
+            retValue = checkAndloadDefinitions(customizationKey);
+        }
+        return retValue;
+    }
+
+    /**
+     * Sets the flag to check source refresh. If not called, the default is
+     * <code>false</code>.
+     *
+     * @param checkRefresh When <code>true</code>, enables automatic checking
+     * of sources changing.
+     * @since 2.1.0
+     */
+    public void setCheckRefresh(boolean checkRefresh) {
+        this.checkRefresh = checkRefresh;
+    }
+
+    /**
+     * Returns a definition from the definition resolver.
+     *
+     * @param name The name of the definition.
+     * @param customizationKey The customization key to use.
+     * @return The resolved definition.
+     */
+    protected Definition getDefinitionFromResolver(String name,
+            Locale customizationKey) {
+        return definitionResolver.resolveDefinition(name,
+                customizationKey);
+    }
+
+    /**
+     * Checks if sources have changed. If yes, it clears the cache. Then continues
+     * loading definitions.
+     *
+     * @param customizationKey The locale to use when loading sources.
+     * @return The loaded definitions.
+     * @since 2.1.0
+     */
+    protected synchronized Map<String, Definition> checkAndloadDefinitions(Locale customizationKey) {
+        Map<String, Definition> existingDefinitions = locale2definitionMap.get(customizationKey);
+        boolean definitionsAlreadyLoaded = existingDefinitions != null;
+        if (definitionsAlreadyLoaded) {
+            return existingDefinitions;
+        }
+        if (checkRefresh && refreshRequired()) {
+            locale2definitionMap.clear();
+            definitionResolver.clearPatternPaths(customizationKey);
+        }
+        loadDefinitions(customizationKey);
+        return locale2definitionMap.get(customizationKey);
+    }
+
+    /**
+     * Tries to load definitions if necessary.
+     *
+     * @param customizationKey The locale to use when loading sources.
+     * @return The loaded definitions.
+     * @since 2.1.0
+     */
+    protected Map<String, Definition> loadDefinitions(Locale customizationKey) {
+        Map<String, Definition> localeDefsMap = locale2definitionMap
+                .get(customizationKey);
+        if (localeDefsMap != null) {
+            return localeDefsMap;
+        }
+
+        return loadDefinitionsFromResources(customizationKey);
+    }
+
+    /**
+     * Loads definitions from the sources.
+     *
+     * @param customizationKey The locale to use when loading Resources.
+     * @return The loaded definitions.
+     * @since 2.1.0
+     */
+    protected Map<String, Definition> loadDefinitionsFromResources(Locale customizationKey) {
+        Map<String, Definition> localeDefsMap = loadRawDefinitionsFromResources(customizationKey);
+        Map<String, Definition> defsMap = definitionResolver
+                .storeDefinitionPatterns(copyDefinitionMap(localeDefsMap),
+                        customizationKey);
+        locale2definitionMap.put(customizationKey, defsMap);
+        return localeDefsMap;
+    }
+
+    /**
+     * Loads the raw definitions from the sources associated with a locale.
+     *
+     * @param customizationKey The locale to use when loading Resources.
+     * @return The loaded definitions.
+     * @since 2.1.3
+     */
+/**
+ * Loads the raw definitions from the sources associated with a locale.
+ *
+ * @param customizationKey
+ * 		The locale to use when loading Resources.
+ * @return The loaded definitions.
+ * @since 2.1.3
+ */
+protected java.util.Map<java.lang.String, org.apache.tiles.Definition> loadRawDefinitionsFromResources(java.util.Locale customizationKey) {
+    java.util.Map<java.lang.String, org.apache.tiles.Definition> localeDefsMap;
+    java.util.Locale parentLocale = org.apache.tiles.request.locale.LocaleUtil.getParentLocale(customizationKey);
+    localeDefsMap = new java.util.LinkedHashMap<java.lang.String, org.apache.tiles.Definition>();
+    if (parentLocale != null) {
+        java.util.Map<java.lang.String, org.apache.tiles.Definition> parentDefs = loadRawDefinitionsFromResources(parentLocale);
+        if (parentDefs != null) {
+            localeDefsMap.putAll(parentDefs);
+        }
+    }
+    // For each source, the resource must be loaded.
+    for (org.apache.tiles.request.ApplicationResource resource : sources) {
+        org.apache.tiles.request.ApplicationResource newResource = applicationContext.getResource(resource, customizationKey);
+        {
+            java.util.Map<java.lang.String, org.apache.tiles.Definition> defsMap = loadDefinitionsFromResource(/* NPEX_NULL_EXP */
+            newResource);
+            if (defsMap != null) {
+                localeDefsMap.putAll(defsMap);
+            }
+        }
+    }
+    return localeDefsMap;
+}
+
+    /**
+     * Loads parent definitions, i.e. definitions mapped to a parent locale.
+     *
+     * @param parentLocale The locale to use when loading URLs.
+     * @return The loaded parent definitions.
+     * @since 2.1.0
+     */
+    protected Map<String, Definition> loadParentDefinitions(Locale parentLocale) {
+        return loadDefinitions(parentLocale);
+    }
+
+    /**
+     * Copies the definition map to be passed to a higher level of customization
+     * key.
+     *
+     * @param localeDefsMap The map of definition to be copied.
+     * @return The copy of the definition map. This particular implementation
+     * return the <code>localeDefsMap</code> itself.
+     * @since 2.1.4
+     */
+    protected Map<String, Definition> copyDefinitionMap(
+            Map<String, Definition> localeDefsMap) {
+        return localeDefsMap;
+    }
+}
diff --git a/Java/tiles-CachingLocaleUrlDefinitionDAO_238/metadata.json b/Java/tiles-CachingLocaleUrlDefinitionDAO_238/metadata.json
new file mode 100644
index 000000000..d8c194ba3
--- /dev/null
+++ b/Java/tiles-CachingLocaleUrlDefinitionDAO_238/metadata.json
@@ -0,0 +1,21 @@
+{
+  "language": "java",
+  "id": "tiles-CachingLocaleUrlDefinitionDAO_238",
+  "buggyPath": ".",
+  "referencePath": null,
+  "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+  "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+  "categories": [
+    "safety",
+    "npe"
+  ],
+  "npe": {
+    "filepath": "tiles-core/src/main/java/org/apache/tiles/definition/dao/CachingLocaleUrlDefinitionDAO.java",
+    "line": 246,
+    "npe_method": "loadRawDefinitionsFromResources",
+    "deref_field": "newResource",
+    "npe_class": "CachingLocaleUrlDefinitionDAO",
+    "repo": "tiles",
+    "bug_id": "CachingLocaleUrlDefinitionDAO_238"
+  }
+}
diff --git a/Java/tiles-CachingLocaleUrlDefinitionDAO_238/npe.json b/Java/tiles-CachingLocaleUrlDefinitionDAO_238/npe.json
new file mode 100644
index 000000000..247a6912f
--- /dev/null
+++ b/Java/tiles-CachingLocaleUrlDefinitionDAO_238/npe.json
@@ -0,0 +1,7 @@
+{
+    "filepath": "tiles-core/src/main/java/org/apache/tiles/definition/dao/CachingLocaleUrlDefinitionDAO.java",
+    "line": 246,
+    "npe_method": "loadRawDefinitionsFromResources",
+    "deref_field": "newResource",
+    "npe_class": "CachingLocaleUrlDefinitionDAO"
+}
\ No newline at end of file
diff --git a/Java/tiles-CachingLocaleUrlDefinitionDAO_240/Dockerfile b/Java/tiles-CachingLocaleUrlDefinitionDAO_240/Dockerfile
new file mode 100644
index 000000000..6bd79b5d5
--- /dev/null
+++ b/Java/tiles-CachingLocaleUrlDefinitionDAO_240/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:tiles
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+    && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+    && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+    && mv /tmp/buggy.java $BUGGY_PATH \
+    && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/tiles-CachingLocaleUrlDefinitionDAO_240/buggy.java b/Java/tiles-CachingLocaleUrlDefinitionDAO_240/buggy.java
new file mode 100644
index 000000000..451a29889
--- /dev/null
+++ b/Java/tiles-CachingLocaleUrlDefinitionDAO_240/buggy.java
@@ -0,0 +1,279 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition.dao;
+
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.tiles.Definition;
+import org.apache.tiles.definition.pattern.PatternDefinitionResolver;
+import org.apache.tiles.definition.pattern.PatternDefinitionResolverAware;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.ApplicationResource;
+import org.apache.tiles.request.locale.LocaleUtil;
+
+/**
+ * <p>
+ * A definitions DAO (loading URLs and using Locale as a customization key) that
+ * caches definitions that have been loaded in a raw way (i.e. with inheritance
+ * that is not resolved).
+ * </p>
+ * <p>
+ * It can check if the URLs change, but by default this feature is turned off.
+ * </p>
+ *
+ * @version $Rev$ $Date$
+ * @since 2.1.0
+ */
+public class CachingLocaleUrlDefinitionDAO extends BaseLocaleUrlDefinitionDAO
+        implements PatternDefinitionResolverAware<Locale> {
+
+    /**
+     * Initialization parameter to set whether we want to refresh URLs when they
+     * change.
+     *
+     * @since 2.1.0
+     */
+    public static final String CHECK_REFRESH_INIT_PARAMETER =
+        "org.apache.tiles.definition.dao.LocaleUrlDefinitionDAO.CHECK_REFRESH";
+
+    /**
+     * The locale-specific set of definitions objects.
+     *
+     * @since 2.1.0
+     */
+    protected Map<Locale, Map<String, Definition>> locale2definitionMap;
+
+    /**
+     * Flag that, when <code>true</code>, enables automatic checking of URLs
+     * changing.
+     *
+     * @since 2.1.0
+     */
+    protected boolean checkRefresh = false;
+
+    /**
+     * Resolves definitions using patterns.
+     *
+     * @since 2.2.0
+     */
+    protected PatternDefinitionResolver<Locale> definitionResolver;
+
+    /**
+     * Constructor.
+     *
+     * @since 2.1.0
+     */
+    public CachingLocaleUrlDefinitionDAO(ApplicationContext applicationContext) {
+        super(applicationContext);
+        locale2definitionMap = new HashMap<Locale, Map<String, Definition>>();
+    }
+
+    /** {@inheritDoc} */
+    public void setPatternDefinitionResolver(
+            PatternDefinitionResolver<Locale> definitionResolver) {
+        this.definitionResolver = definitionResolver;
+    }
+
+    /** {@inheritDoc} */
+    public Definition getDefinition(String name, Locale customizationKey) {
+        Definition retValue = null;
+        if (customizationKey == null) {
+            customizationKey = Locale.ROOT;
+        }
+        Map<String, Definition> definitions = getDefinitions(customizationKey);
+        if (definitions != null) {
+            retValue = definitions.get(name);
+
+            if (retValue == null) {
+                retValue = getDefinitionFromResolver(name, customizationKey);
+
+                if (retValue != null) {
+                    synchronized (definitions) {
+                        definitions.put(name, retValue);
+                    }
+                }
+            }
+        }
+
+        return retValue;
+    }
+
+    /** {@inheritDoc} */
+    public Map<String, Definition> getDefinitions(Locale customizationKey) {
+        if (customizationKey == null) {
+            customizationKey = Locale.ROOT;
+        }
+        Map<String, Definition> retValue = locale2definitionMap
+                .get(customizationKey);
+        if (retValue == null || (checkRefresh && refreshRequired())) {
+            retValue = checkAndloadDefinitions(customizationKey);
+        }
+        return retValue;
+    }
+
+    /**
+     * Sets the flag to check source refresh. If not called, the default is
+     * <code>false</code>.
+     *
+     * @param checkRefresh When <code>true</code>, enables automatic checking
+     * of sources changing.
+     * @since 2.1.0
+     */
+    public void setCheckRefresh(boolean checkRefresh) {
+        this.checkRefresh = checkRefresh;
+    }
+
+    /**
+     * Returns a definition from the definition resolver.
+     *
+     * @param name The name of the definition.
+     * @param customizationKey The customization key to use.
+     * @return The resolved definition.
+     */
+    protected Definition getDefinitionFromResolver(String name,
+            Locale customizationKey) {
+        return definitionResolver.resolveDefinition(name,
+                customizationKey);
+    }
+
+    /**
+     * Checks if sources have changed. If yes, it clears the cache. Then continues
+     * loading definitions.
+     *
+     * @param customizationKey The locale to use when loading sources.
+     * @return The loaded definitions.
+     * @since 2.1.0
+     */
+    protected synchronized Map<String, Definition> checkAndloadDefinitions(Locale customizationKey) {
+        Map<String, Definition> existingDefinitions = locale2definitionMap.get(customizationKey);
+        boolean definitionsAlreadyLoaded = existingDefinitions != null;
+        if (definitionsAlreadyLoaded) {
+            return existingDefinitions;
+        }
+        if (checkRefresh && refreshRequired()) {
+            locale2definitionMap.clear();
+            definitionResolver.clearPatternPaths(customizationKey);
+        }
+        loadDefinitions(customizationKey);
+        return locale2definitionMap.get(customizationKey);
+    }
+
+    /**
+     * Tries to load definitions if necessary.
+     *
+     * @param customizationKey The locale to use when loading sources.
+     * @return The loaded definitions.
+     * @since 2.1.0
+     */
+    protected Map<String, Definition> loadDefinitions(Locale customizationKey) {
+        Map<String, Definition> localeDefsMap = locale2definitionMap
+                .get(customizationKey);
+        if (localeDefsMap != null) {
+            return localeDefsMap;
+        }
+
+        return loadDefinitionsFromResources(customizationKey);
+    }
+
+    /**
+     * Loads definitions from the sources.
+     *
+     * @param customizationKey The locale to use when loading Resources.
+     * @return The loaded definitions.
+     * @since 2.1.0
+     */
+    protected Map<String, Definition> loadDefinitionsFromResources(Locale customizationKey) {
+        Map<String, Definition> localeDefsMap = loadRawDefinitionsFromResources(customizationKey);
+        Map<String, Definition> defsMap = definitionResolver
+                .storeDefinitionPatterns(copyDefinitionMap(localeDefsMap),
+                        customizationKey);
+        locale2definitionMap.put(customizationKey, defsMap);
+        return localeDefsMap;
+    }
+
+    /**
+     * Loads the raw definitions from the sources associated with a locale.
+     *
+     * @param customizationKey The locale to use when loading Resources.
+     * @return The loaded definitions.
+     * @since 2.1.3
+     */
+/**
+ * Loads the raw definitions from the sources associated with a locale.
+ *
+ * @param customizationKey
+ * 		The locale to use when loading Resources.
+ * @return The loaded definitions.
+ * @since 2.1.3
+ */
+protected java.util.Map<java.lang.String, org.apache.tiles.Definition> loadRawDefinitionsFromResources(java.util.Locale customizationKey) {
+    java.util.Map<java.lang.String, org.apache.tiles.Definition> localeDefsMap;
+    java.util.Locale parentLocale = org.apache.tiles.request.locale.LocaleUtil.getParentLocale(customizationKey);
+    localeDefsMap = new java.util.LinkedHashMap<java.lang.String, org.apache.tiles.Definition>();
+    if (parentLocale != null) {
+        java.util.Map<java.lang.String, org.apache.tiles.Definition> parentDefs = loadRawDefinitionsFromResources(parentLocale);
+        if (parentDefs != null) {
+            localeDefsMap.putAll(parentDefs);
+        }
+    }
+    // For each source, the resource must be loaded.
+    for (org.apache.tiles.request.ApplicationResource resource : sources) {
+        org.apache.tiles.request.ApplicationResource newResource = applicationContext.getResource(resource, customizationKey);
+        {
+            java.util.Map<java.lang.String, org.apache.tiles.Definition> defsMap = loadDefinitionsFromResource(newResource);
+            {
+                localeDefsMap.putAll(/* NPEX_NULL_EXP */
+                defsMap);
+            }
+        }
+    }
+    return localeDefsMap;
+}
+
+    /**
+     * Loads parent definitions, i.e. definitions mapped to a parent locale.
+     *
+     * @param parentLocale The locale to use when loading URLs.
+     * @return The loaded parent definitions.
+     * @since 2.1.0
+     */
+    protected Map<String, Definition> loadParentDefinitions(Locale parentLocale) {
+        return loadDefinitions(parentLocale);
+    }
+
+    /**
+     * Copies the definition map to be passed to a higher level of customization
+     * key.
+     *
+     * @param localeDefsMap The map of definition to be copied.
+     * @return The copy of the definition map. This particular implementation
+     * return the <code>localeDefsMap</code> itself.
+     * @since 2.1.4
+     */
+    protected Map<String, Definition> copyDefinitionMap(
+            Map<String, Definition> localeDefsMap) {
+        return localeDefsMap;
+    }
+}
diff --git a/Java/tiles-CachingLocaleUrlDefinitionDAO_240/metadata.json b/Java/tiles-CachingLocaleUrlDefinitionDAO_240/metadata.json
new file mode 100644
index 000000000..de2f0804e
--- /dev/null
+++ b/Java/tiles-CachingLocaleUrlDefinitionDAO_240/metadata.json
@@ -0,0 +1,21 @@
+{
+  "language": "java",
+  "id": "tiles-CachingLocaleUrlDefinitionDAO_240",
+  "buggyPath": ".",
+  "referencePath": null,
+  "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+  "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+  "categories": [
+    "safety",
+    "npe"
+  ],
+  "npe": {
+    "filepath": "tiles-core/src/main/java/org/apache/tiles/definition/dao/CachingLocaleUrlDefinitionDAO.java",
+    "line": 248,
+    "npe_method": "loadRawDefinitionsFromResources",
+    "deref_field": "defsMap",
+    "npe_class": "CachingLocaleUrlDefinitionDAO",
+    "repo": "tiles",
+    "bug_id": "CachingLocaleUrlDefinitionDAO_240"
+  }
+}
diff --git a/Java/tiles-CachingLocaleUrlDefinitionDAO_240/npe.json b/Java/tiles-CachingLocaleUrlDefinitionDAO_240/npe.json
new file mode 100644
index 000000000..f553177fb
--- /dev/null
+++ b/Java/tiles-CachingLocaleUrlDefinitionDAO_240/npe.json
@@ -0,0 +1,7 @@
+{
+    "filepath": "tiles-core/src/main/java/org/apache/tiles/definition/dao/CachingLocaleUrlDefinitionDAO.java",
+    "line": 248,
+    "npe_method": "loadRawDefinitionsFromResources",
+    "deref_field": "defsMap",
+    "npe_class": "CachingLocaleUrlDefinitionDAO"
+}
\ No newline at end of file
diff --git a/Java/tiles-DigesterDefinitionsReader_164/Dockerfile b/Java/tiles-DigesterDefinitionsReader_164/Dockerfile
new file mode 100644
index 000000000..6bd79b5d5
--- /dev/null
+++ b/Java/tiles-DigesterDefinitionsReader_164/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:tiles
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+    && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+    && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+    && mv /tmp/buggy.java $BUGGY_PATH \
+    && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/tiles-DigesterDefinitionsReader_164/buggy.java b/Java/tiles-DigesterDefinitionsReader_164/buggy.java
new file mode 100644
index 000000000..01b57f036
--- /dev/null
+++ b/Java/tiles-DigesterDefinitionsReader_164/buggy.java
@@ -0,0 +1,469 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition.digester;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.apache.commons.digester.Digester;
+import org.apache.commons.digester.Rule;
+import org.apache.tiles.Attribute;
+import org.apache.tiles.Definition;
+import org.apache.tiles.Expression;
+import org.apache.tiles.ListAttribute;
+import org.apache.tiles.definition.DefinitionsFactoryException;
+import org.apache.tiles.definition.DefinitionsReader;
+import org.xml.sax.Attributes;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+/**
+ * Reads {@link Definition} objects from
+ * an XML InputStream using Digester. <p/>
+ * <p>
+ * This <code>DefinitionsReader</code> implementation expects the source to be
+ * passed as an <code>InputStream</code>. It parses XML data from the source
+ * and builds a Map of Definition objects.
+ * </p>
+ * <p/>
+ * <p>
+ * The Digester object can be configured by passing in initialization
+ * parameters. Currently the only parameter that is supported is the
+ * <code>validating</code> parameter. This value is set to <code>false</code>
+ * by default. To enable DTD validation for XML Definition files, give the init
+ * method a parameter with a key of
+ * <code>org.apache.tiles.definition.digester.DigesterDefinitionsReader.PARSER_VALIDATE</code>
+ * and a value of <code>&quot;true&quot;</code>. <p/>
+ * <p>
+ * The Definition objects are stored internally in a Map. The Map is stored as
+ * an instance variable rather than a local variable in the <code>read</code>
+ * method. This means that instances of this class are <strong>not</strong>
+ * thread-safe and access by multiple threads must be synchronized.
+ * </p>
+ *
+ * @version $Rev$ $Date$
+ */
+public class DigesterDefinitionsReader implements DefinitionsReader {
+
+    /**
+     * Digester validation parameter name.
+     */
+    public static final String PARSER_VALIDATE_PARAMETER_NAME =
+        "org.apache.tiles.definition.digester.DigesterDefinitionsReader.PARSER_VALIDATE";
+
+    // Digester rules constants for tag interception.
+
+    /**
+     * Intercepts a &lt;definition&gt; tag.
+     */
+    private static final String DEFINITION_TAG = "tiles-definitions/definition";
+
+    /**
+     * Intercepts a &lt;put-attribute&gt; tag.
+     */
+    private static final String PUT_TAG = "*/definition/put-attribute";
+
+    /**
+     * Intercepts a &lt;definition&gt; inside a  &lt;put-attribute&gt; tag.
+     */
+    private static final String PUT_DEFINITION_TAG = "*/put-attribute/definition";
+
+    /**
+     * Intercepts a &lt;definition&gt; inside an &lt;add-attribute&gt; tag.
+     */
+    private static final String ADD_DEFINITION_TAG = "*/add-attribute/definition";
+
+    /**
+     * Intercepts a &lt;put-list-attribute&gt; tag inside a %lt;definition&gt;
+     * tag.
+     */
+    private static final String DEF_LIST_TAG = "*/definition/put-list-attribute";
+
+    /**
+     * Intercepts a &lt;add-attribute&gt; tag.
+     */
+    private static final String ADD_LIST_ELE_TAG = "*/add-attribute";
+
+    /**
+     * Intercepts a &lt;add-list-attribute&gt; tag.
+     */
+    private static final String NESTED_LIST = "*/add-list-attribute";
+
+    // Handler class names.
+
+    /**
+     * The handler to create definitions.
+     *
+     * @since 2.1.0
+     */
+    protected static final String DEFINITION_HANDLER_CLASS =
+        Definition.class.getName();
+
+    /**
+     * The handler to create attributes.
+     *
+     * @since 2.1.0
+     */
+    protected static final String PUT_ATTRIBUTE_HANDLER_CLASS =
+        Attribute.class.getName();
+
+    /**
+     * The handler to create list attributes.
+     *
+     * @since 2.1.0
+     */
+    protected static final String LIST_HANDLER_CLASS =
+        ListAttribute.class.getName();
+
+    /**
+     * Digester rule to manage definition filling.
+     *
+     * @since 2.1.2
+     */
+    public static class FillDefinitionRule extends Rule {
+
+        /** {@inheritDoc} */
+        @Override
+/**
+ * {@inheritDoc }
+ */
+public void begin(java.lang.String namespace, java.lang.String name, org.xml.sax.Attributes attributes) {
+    org.apache.tiles.Definition definition = ((org.apache.tiles.Definition) (digester.peek()));
+    definition.setName(attributes.getValue("name"));
+    definition.setPreparer(attributes.getValue("preparer"));
+    java.lang.String extendsAttribute = attributes.getValue("extends");
+    definition.setExtends(extendsAttribute);
+    java.lang.String template = attributes.getValue("template");
+    org.apache.tiles.Attribute attribute = org.apache.tiles.Attribute.createTemplateAttribute(template);
+    attribute.setExpressionObject(org.apache.tiles.Expression.createExpressionFromDescribedExpression(attributes.getValue("templateExpression")));
+    attribute.setRole(attributes.getValue("role"));
+    java.lang.String templateType = attributes.getValue("templateType");
+    {
+        attribute.setRenderer(/* NPEX_NULL_EXP */
+        templateType);
+    }
+    definition.setTemplateAttribute(attribute);
+}
+    }
+
+    /**
+     * Digester rule to manage attribute filling.
+     *
+     * @since 2.1.0
+     */
+    public static class FillAttributeRule extends Rule {
+
+        /** {@inheritDoc} */
+        @Override
+        public void begin(String namespace, String name, Attributes attributes) {
+            Attribute attribute = (Attribute) digester.peek();
+            attribute.setValue(attributes.getValue("value"));
+            String expression = attributes.getValue("expression");
+            attribute.setExpressionObject(Expression
+                    .createExpressionFromDescribedExpression(expression));
+            attribute.setRole(attributes.getValue("role"));
+            attribute.setRenderer(attributes.getValue("type"));
+        }
+    }
+
+    /**
+     * Digester rule to manage assignment of the attribute to the parent
+     * element.
+     *
+     * @since 2.1.0
+     */
+    public static class PutAttributeRule extends Rule {
+
+        /** {@inheritDoc} */
+        @Override
+        public void begin(String namespace, String name, Attributes attributes) {
+            Attribute attribute = (Attribute) digester.peek(0);
+            Definition definition = (Definition) digester.peek(1);
+            definition.putAttribute(attributes.getValue("name"), attribute,
+                    "true".equals(attributes.getValue("cascade")));
+        }
+    }
+
+    /**
+     * Digester rule to manage assignment of a nested definition in an attribute
+     * value.
+     *
+     * @since 2.1.0
+     */
+    public class AddNestedDefinitionRule extends Rule {
+
+        /** {@inheritDoc} */
+        @Override
+        public void begin(String namespace, String name, Attributes attributes) {
+            Definition definition = (Definition) digester.peek(0);
+            if (definition.getName() == null) {
+                definition.setName(getNextUniqueDefinitionName(definitions));
+            }
+            Attribute attribute = (Attribute) digester.peek(1);
+            attribute.setValue(definition.getName());
+            attribute.setRenderer("definition");
+        }
+    }
+
+    /**
+     * <code>Digester</code> object used to read Definition data
+     * from the source.
+     */
+    protected Digester digester;
+
+    /**
+     * The set of public identifiers, and corresponding resource names for
+     * the versions of the configuration file DTDs we know about.  There
+     * <strong>MUST</strong> be an even number of Strings in this list!
+     */
+    protected String[] registrations;
+
+    /**
+     * Stores Definition objects.
+     */
+    private Map<String, Definition> definitions;
+
+    /**
+     * Index to be used to create unique definition names for anonymous
+     * (nested) definitions.
+     */
+    private int anonymousDefinitionIndex = 1;
+
+    /**
+     * Creates a new instance of DigesterDefinitionsReader.
+     */
+    public DigesterDefinitionsReader() {
+        digester = new Digester();
+        digester.setNamespaceAware(true);
+        digester.setUseContextClassLoader(true);
+        digester.setErrorHandler(new ThrowingErrorHandler());
+
+        // Register our local copy of the DTDs that we can find
+        String[] registrations = getRegistrations();
+        for (int i = 0; i < registrations.length; i += 2) {
+            URL url = this.getClass().getResource(
+                registrations[i + 1]);
+            if (url != null) {
+                digester.register(registrations[i], url.toString());
+            }
+        }
+
+        initSyntax(digester);
+    }
+
+    /**
+     * Sets the validation of XML files.
+     *
+     * @param validating <code>true</code> means that XML validation is turned
+     * on. <code>false</code> otherwise.
+     * @since 3.3.0
+     */
+    public void setValidating(boolean validating) {
+        digester.setValidating(validating);
+    }
+
+    /**
+     * Reads <code>{@link Definition}</code> objects from a source.
+     * <p/>
+     * Implementations should publish what type of source object is expected.
+     *
+     * @param source The <code>InputStream</code> source from which definitions
+     *               will be read.
+     * @return a Map of <code>Definition</code> objects read from
+     *         the source.
+     * @throws DefinitionsFactoryException If the source is invalid or
+     *          an error occurs when reading definitions.
+     */
+    public Map<String, Definition> read(Object source) {
+        // This is an instance variable instead of a local variable because
+        // we want to be able to call the addDefinition method to populate it.
+        // But we reset the Map here, which, of course, has threading implications.
+        definitions = new LinkedHashMap<String, Definition>();
+
+        if (source == null) {
+            // Perhaps we should throw an exception here.
+            return null;
+        }
+
+        InputStream input;
+        try {
+            input = (InputStream) source;
+        } catch (ClassCastException e) {
+            throw new DefinitionsFactoryException(
+                "Invalid source type.  Requires java.io.InputStream.", e);
+        }
+
+        try {
+            // set first object in stack
+            //digester.clear();
+            digester.push(this);
+            // parse
+            digester.parse(input);
+
+        } catch (SAXException e) {
+            throw new DefinitionsFactoryException(
+                "XML error reading definitions.", e);
+        } catch (IOException e) {
+            throw new DefinitionsFactoryException(
+                "I/O Error reading definitions.", e);
+        } finally {
+            digester.clear();
+        }
+
+        return definitions;
+    }
+
+    /**
+     * Initialised the syntax for reading XML files containing Tiles
+     * definitions.
+     *
+     * @param digester The digester to initialize.
+     */
+    protected void initSyntax(Digester digester) {
+        initDigesterForTilesDefinitionsSyntax(digester);
+    }
+
+
+    /**
+     * Init digester for Tiles syntax with first element = tiles-definitions.
+     *
+     * @param digester Digester instance to use.
+     */
+    private void initDigesterForTilesDefinitionsSyntax(Digester digester) {
+        // syntax rules
+        digester.addObjectCreate(DEFINITION_TAG, DEFINITION_HANDLER_CLASS);
+        digester.addRule(DEFINITION_TAG, new FillDefinitionRule());
+        digester.addSetNext(DEFINITION_TAG, "addDefinition", DEFINITION_HANDLER_CLASS);
+
+        // nested definition rules
+        digester.addObjectCreate(PUT_DEFINITION_TAG, DEFINITION_HANDLER_CLASS);
+        digester.addRule(PUT_DEFINITION_TAG, new FillDefinitionRule());
+        digester.addSetRoot(PUT_DEFINITION_TAG, "addDefinition");
+        digester.addRule(PUT_DEFINITION_TAG, new AddNestedDefinitionRule());
+        digester.addObjectCreate(ADD_DEFINITION_TAG, DEFINITION_HANDLER_CLASS);
+        digester.addRule(ADD_DEFINITION_TAG, new FillDefinitionRule());
+        digester.addSetRoot(ADD_DEFINITION_TAG, "addDefinition");
+        digester.addRule(ADD_DEFINITION_TAG, new AddNestedDefinitionRule());
+
+        // put / putAttribute rules
+        // Rules for a same pattern are called in order, but rule.end() are called
+        // in reverse order.
+        // SetNext and CallMethod use rule.end() method. So, placing SetNext in
+        // first position ensure it will be called last (sic).
+        digester.addObjectCreate(PUT_TAG, PUT_ATTRIBUTE_HANDLER_CLASS);
+        digester.addRule(PUT_TAG, new FillAttributeRule());
+        digester.addRule(PUT_TAG, new PutAttributeRule());
+        // Definition level list rules
+        // This is rules for lists nested in a definition
+        digester.addObjectCreate(DEF_LIST_TAG, LIST_HANDLER_CLASS);
+        digester.addSetProperties(DEF_LIST_TAG);
+        digester.addRule(DEF_LIST_TAG, new PutAttributeRule());
+        // list elements rules
+        // We use Attribute class to avoid rewriting a new class.
+        // Name part can't be used in listElement attribute.
+        digester.addObjectCreate(ADD_LIST_ELE_TAG, PUT_ATTRIBUTE_HANDLER_CLASS);
+        digester.addRule(ADD_LIST_ELE_TAG, new FillAttributeRule());
+        digester.addSetNext(ADD_LIST_ELE_TAG, "add", PUT_ATTRIBUTE_HANDLER_CLASS);
+
+        // nested list elements rules
+        // Create a list handler, and add it to parent list
+        digester.addObjectCreate(NESTED_LIST, LIST_HANDLER_CLASS);
+        digester.addSetProperties(NESTED_LIST);
+        digester.addSetNext(NESTED_LIST, "add", PUT_ATTRIBUTE_HANDLER_CLASS);
+    }
+
+    /**
+     * Adds a new <code>Definition</code> to the internal Map or replaces
+     * an existing one.
+     *
+     * @param definition The Definition object to be added.
+     */
+    public void addDefinition(Definition definition) {
+        String name = definition.getName();
+        if (name == null) {
+            throw new DigesterDefinitionsReaderException(
+                    "A root definition has been defined with no name");
+        }
+
+        definitions.put(name, definition);
+    }
+
+    /**
+     * Error Handler that throws every exception it receives.
+     */
+    private static class ThrowingErrorHandler implements ErrorHandler {
+
+        /** {@inheritDoc} */
+        public void warning(SAXParseException exception) throws SAXException {
+            throw exception;
+        }
+
+        /** {@inheritDoc} */
+        public void error(SAXParseException exception) throws SAXException {
+            throw exception;
+        }
+
+        /** {@inheritDoc} */
+        public void fatalError(SAXParseException exception) throws SAXException {
+            throw exception;
+        }
+    }
+
+    /**
+     * Returns the registrations for local DTDs.
+     *
+     * @return An array containing the locations for registrations of local
+     * DTDs.
+     * @since 2.1.0
+     */
+    protected String[] getRegistrations() {
+        if (registrations == null) {
+            registrations = new String[] {
+                "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN",
+                "/org/apache/tiles/resources/tiles-config_3_0.dtd"};
+        }
+        return registrations;
+    }
+
+    /**
+     * Create a unique definition name usable to store anonymous definitions.
+     *
+     * @param definitions The already created definitions.
+     * @return The unique definition name to be used to store the definition.
+     * @since 2.1.0
+     */
+    protected String getNextUniqueDefinitionName(
+            Map<String, Definition> definitions) {
+        String candidate;
+
+        do {
+            candidate = "$anonymousDefinition" + anonymousDefinitionIndex;
+            anonymousDefinitionIndex++;
+        } while (definitions.containsKey(candidate));
+
+        return candidate;
+    }
+}
diff --git a/Java/tiles-DigesterDefinitionsReader_164/metadata.json b/Java/tiles-DigesterDefinitionsReader_164/metadata.json
new file mode 100644
index 000000000..96a17388f
--- /dev/null
+++ b/Java/tiles-DigesterDefinitionsReader_164/metadata.json
@@ -0,0 +1,21 @@
+{
+  "language": "java",
+  "id": "tiles-DigesterDefinitionsReader_164",
+  "buggyPath": ".",
+  "referencePath": null,
+  "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+  "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+  "categories": [
+    "safety",
+    "npe"
+  ],
+  "npe": {
+    "filepath": "tiles-core/src/main/java/org/apache/tiles/definition/digester/DigesterDefinitionsReader.java",
+    "line": 166,
+    "npe_method": "begin",
+    "deref_field": "templateType",
+    "npe_class": "FillDefinitionRule",
+    "repo": "tiles",
+    "bug_id": "DigesterDefinitionsReader_164"
+  }
+}
diff --git a/Java/tiles-DigesterDefinitionsReader_164/npe.json b/Java/tiles-DigesterDefinitionsReader_164/npe.json
new file mode 100644
index 000000000..623f08c44
--- /dev/null
+++ b/Java/tiles-DigesterDefinitionsReader_164/npe.json
@@ -0,0 +1,7 @@
+{
+    "filepath": "tiles-core/src/main/java/org/apache/tiles/definition/digester/DigesterDefinitionsReader.java",
+    "line": 166,
+    "npe_method": "begin",
+    "deref_field": "templateType",
+    "npe_class": "FillDefinitionRule"
+}
\ No newline at end of file
diff --git a/Java/tiles-DigesterDefinitionsReader_407/Dockerfile b/Java/tiles-DigesterDefinitionsReader_407/Dockerfile
new file mode 100644
index 000000000..6bd79b5d5
--- /dev/null
+++ b/Java/tiles-DigesterDefinitionsReader_407/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:tiles
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+    && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+    && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+    && mv /tmp/buggy.java $BUGGY_PATH \
+    && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/tiles-DigesterDefinitionsReader_407/buggy.java b/Java/tiles-DigesterDefinitionsReader_407/buggy.java
new file mode 100644
index 000000000..bdd6ad9f8
--- /dev/null
+++ b/Java/tiles-DigesterDefinitionsReader_407/buggy.java
@@ -0,0 +1,475 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition.digester;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.apache.commons.digester.Digester;
+import org.apache.commons.digester.Rule;
+import org.apache.tiles.Attribute;
+import org.apache.tiles.Definition;
+import org.apache.tiles.Expression;
+import org.apache.tiles.ListAttribute;
+import org.apache.tiles.definition.DefinitionsFactoryException;
+import org.apache.tiles.definition.DefinitionsReader;
+import org.xml.sax.Attributes;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+/**
+ * Reads {@link Definition} objects from
+ * an XML InputStream using Digester. <p/>
+ * <p>
+ * This <code>DefinitionsReader</code> implementation expects the source to be
+ * passed as an <code>InputStream</code>. It parses XML data from the source
+ * and builds a Map of Definition objects.
+ * </p>
+ * <p/>
+ * <p>
+ * The Digester object can be configured by passing in initialization
+ * parameters. Currently the only parameter that is supported is the
+ * <code>validating</code> parameter. This value is set to <code>false</code>
+ * by default. To enable DTD validation for XML Definition files, give the init
+ * method a parameter with a key of
+ * <code>org.apache.tiles.definition.digester.DigesterDefinitionsReader.PARSER_VALIDATE</code>
+ * and a value of <code>&quot;true&quot;</code>. <p/>
+ * <p>
+ * The Definition objects are stored internally in a Map. The Map is stored as
+ * an instance variable rather than a local variable in the <code>read</code>
+ * method. This means that instances of this class are <strong>not</strong>
+ * thread-safe and access by multiple threads must be synchronized.
+ * </p>
+ *
+ * @version $Rev$ $Date$
+ */
+public class DigesterDefinitionsReader implements DefinitionsReader {
+
+    /**
+     * Digester validation parameter name.
+     */
+    public static final String PARSER_VALIDATE_PARAMETER_NAME =
+        "org.apache.tiles.definition.digester.DigesterDefinitionsReader.PARSER_VALIDATE";
+
+    // Digester rules constants for tag interception.
+
+    /**
+     * Intercepts a &lt;definition&gt; tag.
+     */
+    private static final String DEFINITION_TAG = "tiles-definitions/definition";
+
+    /**
+     * Intercepts a &lt;put-attribute&gt; tag.
+     */
+    private static final String PUT_TAG = "*/definition/put-attribute";
+
+    /**
+     * Intercepts a &lt;definition&gt; inside a  &lt;put-attribute&gt; tag.
+     */
+    private static final String PUT_DEFINITION_TAG = "*/put-attribute/definition";
+
+    /**
+     * Intercepts a &lt;definition&gt; inside an &lt;add-attribute&gt; tag.
+     */
+    private static final String ADD_DEFINITION_TAG = "*/add-attribute/definition";
+
+    /**
+     * Intercepts a &lt;put-list-attribute&gt; tag inside a %lt;definition&gt;
+     * tag.
+     */
+    private static final String DEF_LIST_TAG = "*/definition/put-list-attribute";
+
+    /**
+     * Intercepts a &lt;add-attribute&gt; tag.
+     */
+    private static final String ADD_LIST_ELE_TAG = "*/add-attribute";
+
+    /**
+     * Intercepts a &lt;add-list-attribute&gt; tag.
+     */
+    private static final String NESTED_LIST = "*/add-list-attribute";
+
+    // Handler class names.
+
+    /**
+     * The handler to create definitions.
+     *
+     * @since 2.1.0
+     */
+    protected static final String DEFINITION_HANDLER_CLASS =
+        Definition.class.getName();
+
+    /**
+     * The handler to create attributes.
+     *
+     * @since 2.1.0
+     */
+    protected static final String PUT_ATTRIBUTE_HANDLER_CLASS =
+        Attribute.class.getName();
+
+    /**
+     * The handler to create list attributes.
+     *
+     * @since 2.1.0
+     */
+    protected static final String LIST_HANDLER_CLASS =
+        ListAttribute.class.getName();
+
+    /**
+     * Digester rule to manage definition filling.
+     *
+     * @since 2.1.2
+     */
+    public static class FillDefinitionRule extends Rule {
+
+        /** {@inheritDoc} */
+        @Override
+        public void begin(String namespace, String name, Attributes attributes) {
+            Definition definition = (Definition) digester.peek();
+            definition.setName(attributes.getValue("name"));
+            definition.setPreparer(attributes.getValue("preparer"));
+            String extendsAttribute = attributes.getValue("extends");
+            definition.setExtends(extendsAttribute);
+
+            String template = attributes.getValue("template");
+            Attribute attribute = Attribute.createTemplateAttribute(template);
+            attribute.setExpressionObject(Expression
+                    .createExpressionFromDescribedExpression(attributes
+                            .getValue("templateExpression")));
+            attribute.setRole(attributes.getValue("role"));
+            String templateType = attributes.getValue("templateType");
+            if (templateType != null) {
+                attribute.setRenderer(templateType);
+            } else if (extendsAttribute != null && templateType == null) {
+                attribute.setRenderer(null);
+            }
+            definition.setTemplateAttribute(attribute);
+        }
+    }
+
+    /**
+     * Digester rule to manage attribute filling.
+     *
+     * @since 2.1.0
+     */
+    public static class FillAttributeRule extends Rule {
+
+        /** {@inheritDoc} */
+        @Override
+        public void begin(String namespace, String name, Attributes attributes) {
+            Attribute attribute = (Attribute) digester.peek();
+            attribute.setValue(attributes.getValue("value"));
+            String expression = attributes.getValue("expression");
+            attribute.setExpressionObject(Expression
+                    .createExpressionFromDescribedExpression(expression));
+            attribute.setRole(attributes.getValue("role"));
+            attribute.setRenderer(attributes.getValue("type"));
+        }
+    }
+
+    /**
+     * Digester rule to manage assignment of the attribute to the parent
+     * element.
+     *
+     * @since 2.1.0
+     */
+    public static class PutAttributeRule extends Rule {
+
+        /** {@inheritDoc} */
+        @Override
+        public void begin(String namespace, String name, Attributes attributes) {
+            Attribute attribute = (Attribute) digester.peek(0);
+            Definition definition = (Definition) digester.peek(1);
+            definition.putAttribute(attributes.getValue("name"), attribute,
+                    "true".equals(attributes.getValue("cascade")));
+        }
+    }
+
+    /**
+     * Digester rule to manage assignment of a nested definition in an attribute
+     * value.
+     *
+     * @since 2.1.0
+     */
+    public class AddNestedDefinitionRule extends Rule {
+
+        /** {@inheritDoc} */
+        @Override
+        public void begin(String namespace, String name, Attributes attributes) {
+            Definition definition = (Definition) digester.peek(0);
+            if (definition.getName() == null) {
+                definition.setName(getNextUniqueDefinitionName(definitions));
+            }
+            Attribute attribute = (Attribute) digester.peek(1);
+            attribute.setValue(definition.getName());
+            attribute.setRenderer("definition");
+        }
+    }
+
+    /**
+     * <code>Digester</code> object used to read Definition data
+     * from the source.
+     */
+    protected Digester digester;
+
+    /**
+     * The set of public identifiers, and corresponding resource names for
+     * the versions of the configuration file DTDs we know about.  There
+     * <strong>MUST</strong> be an even number of Strings in this list!
+     */
+    protected String[] registrations;
+
+    /**
+     * Stores Definition objects.
+     */
+    private Map<String, Definition> definitions;
+
+    /**
+     * Index to be used to create unique definition names for anonymous
+     * (nested) definitions.
+     */
+    private int anonymousDefinitionIndex = 1;
+
+    /**
+     * Creates a new instance of DigesterDefinitionsReader.
+     */
+    public DigesterDefinitionsReader() {
+        digester = new Digester();
+        digester.setNamespaceAware(true);
+        digester.setUseContextClassLoader(true);
+        digester.setErrorHandler(new ThrowingErrorHandler());
+
+        // Register our local copy of the DTDs that we can find
+        String[] registrations = getRegistrations();
+        for (int i = 0; i < registrations.length; i += 2) {
+            URL url = this.getClass().getResource(
+                registrations[i + 1]);
+            if (url != null) {
+                digester.register(registrations[i], url.toString());
+            }
+        }
+
+        initSyntax(digester);
+    }
+
+    /**
+     * Sets the validation of XML files.
+     *
+     * @param validating <code>true</code> means that XML validation is turned
+     * on. <code>false</code> otherwise.
+     * @since 3.3.0
+     */
+    public void setValidating(boolean validating) {
+        digester.setValidating(validating);
+    }
+
+    /**
+     * Reads <code>{@link Definition}</code> objects from a source.
+     * <p/>
+     * Implementations should publish what type of source object is expected.
+     *
+     * @param source The <code>InputStream</code> source from which definitions
+     *               will be read.
+     * @return a Map of <code>Definition</code> objects read from
+     *         the source.
+     * @throws DefinitionsFactoryException If the source is invalid or
+     *          an error occurs when reading definitions.
+     */
+    public Map<String, Definition> read(Object source) {
+        // This is an instance variable instead of a local variable because
+        // we want to be able to call the addDefinition method to populate it.
+        // But we reset the Map here, which, of course, has threading implications.
+        definitions = new LinkedHashMap<String, Definition>();
+
+        if (source == null) {
+            // Perhaps we should throw an exception here.
+            return null;
+        }
+
+        InputStream input;
+        try {
+            input = (InputStream) source;
+        } catch (ClassCastException e) {
+            throw new DefinitionsFactoryException(
+                "Invalid source type.  Requires java.io.InputStream.", e);
+        }
+
+        try {
+            // set first object in stack
+            //digester.clear();
+            digester.push(this);
+            // parse
+            digester.parse(input);
+
+        } catch (SAXException e) {
+            throw new DefinitionsFactoryException(
+                "XML error reading definitions.", e);
+        } catch (IOException e) {
+            throw new DefinitionsFactoryException(
+                "I/O Error reading definitions.", e);
+        } finally {
+            digester.clear();
+        }
+
+        return definitions;
+    }
+
+    /**
+     * Initialised the syntax for reading XML files containing Tiles
+     * definitions.
+     *
+     * @param digester The digester to initialize.
+     */
+    protected void initSyntax(Digester digester) {
+        initDigesterForTilesDefinitionsSyntax(digester);
+    }
+
+
+    /**
+     * Init digester for Tiles syntax with first element = tiles-definitions.
+     *
+     * @param digester Digester instance to use.
+     */
+    private void initDigesterForTilesDefinitionsSyntax(Digester digester) {
+        // syntax rules
+        digester.addObjectCreate(DEFINITION_TAG, DEFINITION_HANDLER_CLASS);
+        digester.addRule(DEFINITION_TAG, new FillDefinitionRule());
+        digester.addSetNext(DEFINITION_TAG, "addDefinition", DEFINITION_HANDLER_CLASS);
+
+        // nested definition rules
+        digester.addObjectCreate(PUT_DEFINITION_TAG, DEFINITION_HANDLER_CLASS);
+        digester.addRule(PUT_DEFINITION_TAG, new FillDefinitionRule());
+        digester.addSetRoot(PUT_DEFINITION_TAG, "addDefinition");
+        digester.addRule(PUT_DEFINITION_TAG, new AddNestedDefinitionRule());
+        digester.addObjectCreate(ADD_DEFINITION_TAG, DEFINITION_HANDLER_CLASS);
+        digester.addRule(ADD_DEFINITION_TAG, new FillDefinitionRule());
+        digester.addSetRoot(ADD_DEFINITION_TAG, "addDefinition");
+        digester.addRule(ADD_DEFINITION_TAG, new AddNestedDefinitionRule());
+
+        // put / putAttribute rules
+        // Rules for a same pattern are called in order, but rule.end() are called
+        // in reverse order.
+        // SetNext and CallMethod use rule.end() method. So, placing SetNext in
+        // first position ensure it will be called last (sic).
+        digester.addObjectCreate(PUT_TAG, PUT_ATTRIBUTE_HANDLER_CLASS);
+        digester.addRule(PUT_TAG, new FillAttributeRule());
+        digester.addRule(PUT_TAG, new PutAttributeRule());
+        // Definition level list rules
+        // This is rules for lists nested in a definition
+        digester.addObjectCreate(DEF_LIST_TAG, LIST_HANDLER_CLASS);
+        digester.addSetProperties(DEF_LIST_TAG);
+        digester.addRule(DEF_LIST_TAG, new PutAttributeRule());
+        // list elements rules
+        // We use Attribute class to avoid rewriting a new class.
+        // Name part can't be used in listElement attribute.
+        digester.addObjectCreate(ADD_LIST_ELE_TAG, PUT_ATTRIBUTE_HANDLER_CLASS);
+        digester.addRule(ADD_LIST_ELE_TAG, new FillAttributeRule());
+        digester.addSetNext(ADD_LIST_ELE_TAG, "add", PUT_ATTRIBUTE_HANDLER_CLASS);
+
+        // nested list elements rules
+        // Create a list handler, and add it to parent list
+        digester.addObjectCreate(NESTED_LIST, LIST_HANDLER_CLASS);
+        digester.addSetProperties(NESTED_LIST);
+        digester.addSetNext(NESTED_LIST, "add", PUT_ATTRIBUTE_HANDLER_CLASS);
+    }
+
+    /**
+     * Adds a new <code>Definition</code> to the internal Map or replaces
+     * an existing one.
+     *
+     * @param definition The Definition object to be added.
+     */
+/**
+ * Adds a new <code>Definition</code> to the internal Map or replaces
+ * an existing one.
+ *
+ * @param definition
+ * 		The Definition object to be added.
+ */
+public void addDefinition(org.apache.tiles.Definition definition) {
+    java.lang.String name = definition.getName();
+    {
+        definitions.put(/* NPEX_NULL_EXP */
+        name, definition);
+    }
+}
+
+    /**
+     * Error Handler that throws every exception it receives.
+     */
+    private static class ThrowingErrorHandler implements ErrorHandler {
+
+        /** {@inheritDoc} */
+        public void warning(SAXParseException exception) throws SAXException {
+            throw exception;
+        }
+
+        /** {@inheritDoc} */
+        public void error(SAXParseException exception) throws SAXException {
+            throw exception;
+        }
+
+        /** {@inheritDoc} */
+        public void fatalError(SAXParseException exception) throws SAXException {
+            throw exception;
+        }
+    }
+
+    /**
+     * Returns the registrations for local DTDs.
+     *
+     * @return An array containing the locations for registrations of local
+     * DTDs.
+     * @since 2.1.0
+     */
+    protected String[] getRegistrations() {
+        if (registrations == null) {
+            registrations = new String[] {
+                "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN",
+                "/org/apache/tiles/resources/tiles-config_3_0.dtd"};
+        }
+        return registrations;
+    }
+
+    /**
+     * Create a unique definition name usable to store anonymous definitions.
+     *
+     * @param definitions The already created definitions.
+     * @return The unique definition name to be used to store the definition.
+     * @since 2.1.0
+     */
+    protected String getNextUniqueDefinitionName(
+            Map<String, Definition> definitions) {
+        String candidate;
+
+        do {
+            candidate = "$anonymousDefinition" + anonymousDefinitionIndex;
+            anonymousDefinitionIndex++;
+        } while (definitions.containsKey(candidate));
+
+        return candidate;
+    }
+}
diff --git a/Java/tiles-DigesterDefinitionsReader_407/metadata.json b/Java/tiles-DigesterDefinitionsReader_407/metadata.json
new file mode 100644
index 000000000..dd96704c0
--- /dev/null
+++ b/Java/tiles-DigesterDefinitionsReader_407/metadata.json
@@ -0,0 +1,21 @@
+{
+  "language": "java",
+  "id": "tiles-DigesterDefinitionsReader_407",
+  "buggyPath": ".",
+  "referencePath": null,
+  "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+  "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+  "categories": [
+    "safety",
+    "npe"
+  ],
+  "npe": {
+    "filepath": "tiles-core/src/main/java/org/apache/tiles/definition/digester/DigesterDefinitionsReader.java",
+    "line": 416,
+    "npe_method": "addDefinition",
+    "deref_field": "name",
+    "npe_class": "DigesterDefinitionsReader",
+    "repo": "tiles",
+    "bug_id": "DigesterDefinitionsReader_407"
+  }
+}
diff --git a/Java/tiles-DigesterDefinitionsReader_407/npe.json b/Java/tiles-DigesterDefinitionsReader_407/npe.json
new file mode 100644
index 000000000..74676d73e
--- /dev/null
+++ b/Java/tiles-DigesterDefinitionsReader_407/npe.json
@@ -0,0 +1,7 @@
+{
+    "filepath": "tiles-core/src/main/java/org/apache/tiles/definition/digester/DigesterDefinitionsReader.java",
+    "line": 416,
+    "npe_method": "addDefinition",
+    "deref_field": "name",
+    "npe_class": "DigesterDefinitionsReader"
+}
\ No newline at end of file
diff --git a/Java/tiles-LocaleUrlDefinitionDAO_74/Dockerfile b/Java/tiles-LocaleUrlDefinitionDAO_74/Dockerfile
new file mode 100644
index 000000000..6bd79b5d5
--- /dev/null
+++ b/Java/tiles-LocaleUrlDefinitionDAO_74/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:tiles
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+    && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+    && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+    && mv /tmp/buggy.java $BUGGY_PATH \
+    && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/tiles-LocaleUrlDefinitionDAO_74/buggy.java b/Java/tiles-LocaleUrlDefinitionDAO_74/buggy.java
new file mode 100644
index 000000000..b5207e15f
--- /dev/null
+++ b/Java/tiles-LocaleUrlDefinitionDAO_74/buggy.java
@@ -0,0 +1,109 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.definition.dao;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.tiles.Definition;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.ApplicationResource;
+import org.apache.tiles.request.locale.LocaleUtil;
+
+/**
+ * A definition DAO that uses {@link Locale} as a customization key and loads
+ * definitions from URLs. It does not cache definitions in any way.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.1.0
+ */
+public class LocaleUrlDefinitionDAO extends BaseLocaleUrlDefinitionDAO {
+
+    public LocaleUrlDefinitionDAO(ApplicationContext applicationContext) {
+        super(applicationContext);
+    }
+
+    /**
+     * <p>
+     * Returns a definition, given its name and the customization key.
+     * </p>
+     * <strong>WARNING!</strong> This method is slow! It loads all the
+     * definitions and then selects the needed one.
+     *
+     * @param name The name of the definition.
+     * @param customizationKey The customization key.
+     * @return The requested definition, if found, otherwise <code>null</code>.
+     * The inheritance of the definition must not be resolved.
+     * @since 2.1.0
+     */
+    public Definition getDefinition(String name, Locale customizationKey) {
+        Map<String, Definition> defsMap = getDefinitions(customizationKey);
+        return defsMap.get(name);
+    }
+
+    /** {@inheritDoc} */
+/**
+ * {@inheritDoc }
+ */
+public java.util.Map<java.lang.String, org.apache.tiles.Definition> getDefinitions(java.util.Locale customizationKey) {
+    java.util.ArrayList<java.util.Locale> postfixes = computeLocales(customizationKey);
+    java.util.Map<java.lang.String, org.apache.tiles.Definition> localeDefsMap = new java.util.HashMap<java.lang.String, org.apache.tiles.Definition>();
+    // process the postfixes from the root to the most specific
+    for (java.util.Locale postfix : postfixes) {
+        // For each postfix, all the sources must be loaded.
+        for (org.apache.tiles.request.ApplicationResource resource : sources) {
+            org.apache.tiles.request.ApplicationResource newResource = applicationContext.getResource(resource, postfix);
+            {
+                java.util.Map<java.lang.String, org.apache.tiles.Definition> defsMap = loadDefinitionsFromResource(/* NPEX_NULL_EXP */
+                newResource);
+                if (defsMap != null) {
+                    localeDefsMap.putAll(defsMap);
+                }
+            }
+        }
+    }
+    return localeDefsMap;
+}
+
+    /**
+     * Returns a list of locales from root to the customizationKey.
+     * @param customizationKey the target Locale.
+     * @return the list of its ancestors.
+     */
+    private ArrayList<Locale> computeLocales(Locale customizationKey) {
+        Locale postfix;
+        if(customizationKey == null) {
+            postfix = Locale.ROOT;
+        } else {
+            postfix = customizationKey;
+        }
+        ArrayList<Locale> postfixes = new ArrayList<Locale>();
+        while (postfix != null) {
+            postfixes.add(postfix);
+            postfix = LocaleUtil.getParentLocale(postfix);
+        }
+        Collections.reverse(postfixes);
+        return postfixes;
+    }
+}
diff --git a/Java/tiles-LocaleUrlDefinitionDAO_74/metadata.json b/Java/tiles-LocaleUrlDefinitionDAO_74/metadata.json
new file mode 100644
index 000000000..7ac0f5922
--- /dev/null
+++ b/Java/tiles-LocaleUrlDefinitionDAO_74/metadata.json
@@ -0,0 +1,21 @@
+{
+  "language": "java",
+  "id": "tiles-LocaleUrlDefinitionDAO_74",
+  "buggyPath": ".",
+  "referencePath": null,
+  "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+  "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+  "categories": [
+    "safety",
+    "npe"
+  ],
+  "npe": {
+    "filepath": "tiles-core/src/main/java/org/apache/tiles/definition/dao/LocaleUrlDefinitionDAO.java",
+    "line": 79,
+    "npe_method": "getDefinitions",
+    "deref_field": "newResource",
+    "npe_class": "LocaleUrlDefinitionDAO",
+    "repo": "tiles",
+    "bug_id": "LocaleUrlDefinitionDAO_74"
+  }
+}
diff --git a/Java/tiles-LocaleUrlDefinitionDAO_74/npe.json b/Java/tiles-LocaleUrlDefinitionDAO_74/npe.json
new file mode 100644
index 000000000..7d976c85a
--- /dev/null
+++ b/Java/tiles-LocaleUrlDefinitionDAO_74/npe.json
@@ -0,0 +1,7 @@
+{
+    "filepath": "tiles-core/src/main/java/org/apache/tiles/definition/dao/LocaleUrlDefinitionDAO.java",
+    "line": 79,
+    "npe_method": "getDefinitions",
+    "deref_field": "newResource",
+    "npe_class": "LocaleUrlDefinitionDAO"
+}
\ No newline at end of file
diff --git a/Java/tiles-LocaleUrlDefinitionDAO_76/Dockerfile b/Java/tiles-LocaleUrlDefinitionDAO_76/Dockerfile
new file mode 100644
index 000000000..6bd79b5d5
--- /dev/null
+++ b/Java/tiles-LocaleUrlDefinitionDAO_76/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:tiles
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+    && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+    && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+    && mv /tmp/buggy.java $BUGGY_PATH \
+    && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/tiles-LocaleUrlDefinitionDAO_76/buggy.java b/Java/tiles-LocaleUrlDefinitionDAO_76/buggy.java
new file mode 100644
index 000000000..399721518
--- /dev/null
+++ b/Java/tiles-LocaleUrlDefinitionDAO_76/buggy.java
@@ -0,0 +1,109 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.definition.dao;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.tiles.Definition;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.ApplicationResource;
+import org.apache.tiles.request.locale.LocaleUtil;
+
+/**
+ * A definition DAO that uses {@link Locale} as a customization key and loads
+ * definitions from URLs. It does not cache definitions in any way.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.1.0
+ */
+public class LocaleUrlDefinitionDAO extends BaseLocaleUrlDefinitionDAO {
+
+    public LocaleUrlDefinitionDAO(ApplicationContext applicationContext) {
+        super(applicationContext);
+    }
+
+    /**
+     * <p>
+     * Returns a definition, given its name and the customization key.
+     * </p>
+     * <strong>WARNING!</strong> This method is slow! It loads all the
+     * definitions and then selects the needed one.
+     *
+     * @param name The name of the definition.
+     * @param customizationKey The customization key.
+     * @return The requested definition, if found, otherwise <code>null</code>.
+     * The inheritance of the definition must not be resolved.
+     * @since 2.1.0
+     */
+    public Definition getDefinition(String name, Locale customizationKey) {
+        Map<String, Definition> defsMap = getDefinitions(customizationKey);
+        return defsMap.get(name);
+    }
+
+    /** {@inheritDoc} */
+/**
+ * {@inheritDoc }
+ */
+public java.util.Map<java.lang.String, org.apache.tiles.Definition> getDefinitions(java.util.Locale customizationKey) {
+    java.util.ArrayList<java.util.Locale> postfixes = computeLocales(customizationKey);
+    java.util.Map<java.lang.String, org.apache.tiles.Definition> localeDefsMap = new java.util.HashMap<java.lang.String, org.apache.tiles.Definition>();
+    // process the postfixes from the root to the most specific
+    for (java.util.Locale postfix : postfixes) {
+        // For each postfix, all the sources must be loaded.
+        for (org.apache.tiles.request.ApplicationResource resource : sources) {
+            org.apache.tiles.request.ApplicationResource newResource = applicationContext.getResource(resource, postfix);
+            {
+                java.util.Map<java.lang.String, org.apache.tiles.Definition> defsMap = loadDefinitionsFromResource(newResource);
+                {
+                    localeDefsMap.putAll(/* NPEX_NULL_EXP */
+                    defsMap);
+                }
+            }
+        }
+    }
+    return localeDefsMap;
+}
+
+    /**
+     * Returns a list of locales from root to the customizationKey.
+     * @param customizationKey the target Locale.
+     * @return the list of its ancestors.
+     */
+    private ArrayList<Locale> computeLocales(Locale customizationKey) {
+        Locale postfix;
+        if(customizationKey == null) {
+            postfix = Locale.ROOT;
+        } else {
+            postfix = customizationKey;
+        }
+        ArrayList<Locale> postfixes = new ArrayList<Locale>();
+        while (postfix != null) {
+            postfixes.add(postfix);
+            postfix = LocaleUtil.getParentLocale(postfix);
+        }
+        Collections.reverse(postfixes);
+        return postfixes;
+    }
+}
diff --git a/Java/tiles-LocaleUrlDefinitionDAO_76/metadata.json b/Java/tiles-LocaleUrlDefinitionDAO_76/metadata.json
new file mode 100644
index 000000000..d9a4628a7
--- /dev/null
+++ b/Java/tiles-LocaleUrlDefinitionDAO_76/metadata.json
@@ -0,0 +1,21 @@
+{
+  "language": "java",
+  "id": "tiles-LocaleUrlDefinitionDAO_76",
+  "buggyPath": ".",
+  "referencePath": null,
+  "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+  "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+  "categories": [
+    "safety",
+    "npe"
+  ],
+  "npe": {
+    "filepath": "tiles-core/src/main/java/org/apache/tiles/definition/dao/LocaleUrlDefinitionDAO.java",
+    "line": 81,
+    "npe_method": "getDefinitions",
+    "deref_field": "defsMap",
+    "npe_class": "LocaleUrlDefinitionDAO",
+    "repo": "tiles",
+    "bug_id": "LocaleUrlDefinitionDAO_76"
+  }
+}
diff --git a/Java/tiles-LocaleUrlDefinitionDAO_76/npe.json b/Java/tiles-LocaleUrlDefinitionDAO_76/npe.json
new file mode 100644
index 000000000..0e42a1e27
--- /dev/null
+++ b/Java/tiles-LocaleUrlDefinitionDAO_76/npe.json
@@ -0,0 +1,7 @@
+{
+    "filepath": "tiles-core/src/main/java/org/apache/tiles/definition/dao/LocaleUrlDefinitionDAO.java",
+    "line": 81,
+    "npe_method": "getDefinitions",
+    "deref_field": "defsMap",
+    "npe_class": "LocaleUrlDefinitionDAO"
+}
\ No newline at end of file
diff --git a/Java/tiles-LocaleUrlDefinitionDAO_92/Dockerfile b/Java/tiles-LocaleUrlDefinitionDAO_92/Dockerfile
new file mode 100644
index 000000000..6bd79b5d5
--- /dev/null
+++ b/Java/tiles-LocaleUrlDefinitionDAO_92/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:tiles
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+    && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+    && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+    && mv /tmp/buggy.java $BUGGY_PATH \
+    && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/tiles-LocaleUrlDefinitionDAO_92/buggy.java b/Java/tiles-LocaleUrlDefinitionDAO_92/buggy.java
new file mode 100644
index 000000000..a4567f2ca
--- /dev/null
+++ b/Java/tiles-LocaleUrlDefinitionDAO_92/buggy.java
@@ -0,0 +1,111 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.definition.dao;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import org.apache.tiles.Definition;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.ApplicationResource;
+import org.apache.tiles.request.locale.LocaleUtil;
+
+/**
+ * A definition DAO that uses {@link Locale} as a customization key and loads
+ * definitions from URLs. It does not cache definitions in any way.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.1.0
+ */
+public class LocaleUrlDefinitionDAO extends BaseLocaleUrlDefinitionDAO {
+
+    public LocaleUrlDefinitionDAO(ApplicationContext applicationContext) {
+        super(applicationContext);
+    }
+
+    /**
+     * <p>
+     * Returns a definition, given its name and the customization key.
+     * </p>
+     * <strong>WARNING!</strong> This method is slow! It loads all the
+     * definitions and then selects the needed one.
+     *
+     * @param name The name of the definition.
+     * @param customizationKey The customization key.
+     * @return The requested definition, if found, otherwise <code>null</code>.
+     * The inheritance of the definition must not be resolved.
+     * @since 2.1.0
+     */
+    public Definition getDefinition(String name, Locale customizationKey) {
+        Map<String, Definition> defsMap = getDefinitions(customizationKey);
+        return defsMap.get(name);
+    }
+
+    /** {@inheritDoc} */
+    public Map<String, Definition> getDefinitions(Locale customizationKey) {
+        ArrayList<Locale> postfixes = computeLocales(customizationKey);
+        Map<String, Definition> localeDefsMap = new HashMap<String, Definition>();
+        // process the postfixes from the root to the most specific
+        for (Locale postfix : postfixes) {
+            // For each postfix, all the sources must be loaded.
+            for (ApplicationResource resource : sources) {
+                ApplicationResource newResource = applicationContext.getResource(resource, postfix);
+                if (newResource != null) {
+                    Map<String, Definition> defsMap = loadDefinitionsFromResource(newResource);
+                    if (defsMap != null) {
+                        localeDefsMap.putAll(defsMap);
+                    }
+                }
+            }
+        }
+        return localeDefsMap;
+    }
+
+    /**
+     * Returns a list of locales from root to the customizationKey.
+     * @param customizationKey the target Locale.
+     * @return the list of its ancestors.
+     */
+/**
+ * Returns a list of locales from root to the customizationKey.
+ *
+ * @param customizationKey
+ * 		the target Locale.
+ * @return the list of its ancestors.
+ */
+private java.util.ArrayList<java.util.Locale> computeLocales(java.util.Locale customizationKey) {
+    java.util.Locale postfix;
+    {
+        postfix = /* NPEX_NULL_EXP */
+        customizationKey;
+    }
+    java.util.ArrayList<java.util.Locale> postfixes = new java.util.ArrayList<java.util.Locale>();
+    while (postfix != null) {
+        postfixes.add(postfix);
+        postfix = org.apache.tiles.request.locale.LocaleUtil.getParentLocale(postfix);
+    } 
+    java.util.Collections.reverse(postfixes);
+    return postfixes;
+}
+}
diff --git a/Java/tiles-LocaleUrlDefinitionDAO_92/metadata.json b/Java/tiles-LocaleUrlDefinitionDAO_92/metadata.json
new file mode 100644
index 000000000..54a8fa525
--- /dev/null
+++ b/Java/tiles-LocaleUrlDefinitionDAO_92/metadata.json
@@ -0,0 +1,21 @@
+{
+  "language": "java",
+  "id": "tiles-LocaleUrlDefinitionDAO_92",
+  "buggyPath": ".",
+  "referencePath": null,
+  "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+  "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+  "categories": [
+    "safety",
+    "npe"
+  ],
+  "npe": {
+    "filepath": "tiles-core/src/main/java/org/apache/tiles/definition/dao/LocaleUrlDefinitionDAO.java",
+    "line": 101,
+    "npe_method": "computeLocales",
+    "deref_field": "customizationKey",
+    "npe_class": "LocaleUrlDefinitionDAO",
+    "repo": "tiles",
+    "bug_id": "LocaleUrlDefinitionDAO_92"
+  }
+}
diff --git a/Java/tiles-LocaleUrlDefinitionDAO_92/npe.json b/Java/tiles-LocaleUrlDefinitionDAO_92/npe.json
new file mode 100644
index 000000000..090d6694b
--- /dev/null
+++ b/Java/tiles-LocaleUrlDefinitionDAO_92/npe.json
@@ -0,0 +1,7 @@
+{
+    "filepath": "tiles-core/src/main/java/org/apache/tiles/definition/dao/LocaleUrlDefinitionDAO.java",
+    "line": 101,
+    "npe_method": "computeLocales",
+    "deref_field": "customizationKey",
+    "npe_class": "LocaleUrlDefinitionDAO"
+}
\ No newline at end of file
diff --git a/Java/tiles-PatternUtil_169/Dockerfile b/Java/tiles-PatternUtil_169/Dockerfile
new file mode 100644
index 000000000..6bd79b5d5
--- /dev/null
+++ b/Java/tiles-PatternUtil_169/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:tiles
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+    && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+    && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+    && mv /tmp/buggy.java $BUGGY_PATH \
+    && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/tiles-PatternUtil_169/buggy.java b/Java/tiles-PatternUtil_169/buggy.java
new file mode 100644
index 000000000..af38f0546
--- /dev/null
+++ b/Java/tiles-PatternUtil_169/buggy.java
@@ -0,0 +1,251 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition.pattern;
+
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.Definition;
+import org.apache.tiles.Expression;
+import org.apache.tiles.ListAttribute;
+
+/**
+ * Utilities for pattern matching and substitution.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public final class PatternUtil {
+
+    /**
+     * The root locale. Notice that this is a replacement for Locale.ROOT for
+     * Java 1.6.
+     */
+    private static final Locale ROOT_LOCALE = new Locale("", "");
+
+    /** Pattern to find {.*} occurrences that do not match {[0-9]+} so to prevent MessageFormat from crashing.
+     */
+    private static final Pattern INVALID_FORMAT_ELEMENT = Pattern.compile("\\{[^}0-9]+\\}");
+
+    /**
+     * Private constructor to avoid instantiation.
+     */
+    private PatternUtil() {
+    }
+
+    /**
+     * Creates a definition given its representation with wildcards and
+     * attribute values with placeholders, replacing real values into
+     * placeholders.
+     *
+     * @param d The definition to replace.
+     * @param name The name of the definition to be created.
+     * @param varsOrig The variables to be substituted.
+     * @return The definition that can be rendered.
+     * @since 2.2.0
+     */
+    public static Definition replacePlaceholders(Definition d, String name,
+            Object... varsOrig) {
+
+        Object[] vars = replaceNullsWithBlank(varsOrig);
+
+        Definition nudef = new Definition();
+
+        nudef.setExtends(replace(d.getExtends(), vars));
+        nudef.setName(name);
+        nudef.setPreparer(replace(d.getPreparer(), vars));
+        Attribute templateAttribute = d.getTemplateAttribute();
+        if (templateAttribute != null) {
+            nudef.setTemplateAttribute(replaceVarsInAttribute(
+                    templateAttribute, vars));
+        }
+
+        Set<String> attributeNames = d.getLocalAttributeNames();
+        if (attributeNames != null && !attributeNames.isEmpty()) {
+            for (String attributeName : attributeNames) {
+                Attribute attr = d.getLocalAttribute(attributeName);
+                Attribute nuattr = replaceVarsInAttribute(attr, vars);
+
+                nudef.putAttribute(replace(attributeName, vars), nuattr);
+            }
+        }
+
+        attributeNames = d.getCascadedAttributeNames();
+        if (attributeNames != null && !attributeNames.isEmpty()) {
+            for (String attributeName : attributeNames) {
+                Attribute attr = d.getCascadedAttribute(attributeName);
+                Attribute nuattr = replaceVarsInAttribute(attr, vars);
+
+                nudef.putAttribute(replace(attributeName, vars), nuattr, true);
+            }
+        }
+
+        return nudef;
+    }
+
+    /**
+     * Creates a new map that contains all the entries of the
+     * <code>defsMap</code> whose keys are contained in <code>keys</code>.
+     *
+     * @param map The map to read.
+     * @param keys The keys to extract.
+     * @param <K> The key of the map.
+     * @param <V> The value of the map.
+     * @return The extracted map.
+     * @since 2.2.1
+     */
+    public static <K, V> Map<K, V> createExtractedMap(Map<K, V> map, Set<K> keys) {
+        Map<K, V> retValue = new LinkedHashMap<K, V>();
+        for (K key : keys) {
+            retValue.put(key, map.get(key));
+        }
+        return retValue;
+    }
+
+    /**
+     * Replaces variables into an attribute.
+     *
+     * @param attr The attribute to be used as a basis, containing placeholders
+     * for variables.
+     * @param vars The variables to replace.
+     * @return A new instance of an attribute, whose properties have been
+     * replaced with variables' values.
+     */
+    private static Attribute replaceVarsInAttribute(Attribute attr,
+            Object... vars) {
+        Attribute nuattr;
+        if (attr instanceof ListAttribute) {
+            nuattr = replaceVarsInListAttribute((ListAttribute) attr, vars);
+        } else {
+            nuattr = replaceVarsInSimpleAttribute(attr, vars);
+        }
+        return nuattr;
+    }
+
+    /**
+     * Replaces variables into a simple (not list) attribute.
+     *
+     * @param attr The attribute to be used as a basis, containing placeholders
+     * for variables.
+     * @param vars The variables to replace.
+     * @return A new instance of an attribute, whose properties have been
+     * replaced with variables' values.
+     */
+/**
+ * Replaces variables into a simple (not list) attribute.
+ *
+ * @param attr
+ * 		The attribute to be used as a basis, containing placeholders
+ * 		for variables.
+ * @param vars
+ * 		The variables to replace.
+ * @return A new instance of an attribute, whose properties have been
+replaced with variables' values.
+ */
+private static org.apache.tiles.Attribute replaceVarsInSimpleAttribute(org.apache.tiles.Attribute attr, java.lang.Object... vars) {
+    org.apache.tiles.Attribute nuattr;
+    nuattr = new org.apache.tiles.Attribute();
+    nuattr.setRole(org.apache.tiles.definition.pattern.PatternUtil.replace(attr.getRole(), vars));
+    nuattr.setRenderer(attr.getRenderer());
+    org.apache.tiles.Expression expressionObject = attr.getExpressionObject();
+    {
+        org.apache.tiles.Expression newExpressionObject = org.apache.tiles.Expression.createExpression(org.apache.tiles.definition.pattern.PatternUtil.replace(/* NPEX_NULL_EXP */
+        expressionObject.getExpression(), vars), expressionObject.getLanguage());
+        nuattr.setExpressionObject(newExpressionObject);
+    }
+    java.lang.Object value = attr.getValue();
+    if (value instanceof java.lang.String) {
+        value = org.apache.tiles.definition.pattern.PatternUtil.replace(((java.lang.String) (value)), vars);
+    }
+    nuattr.setValue(value);
+    return nuattr;
+}
+
+    /**
+     * Replaces variables into a list attribute.
+     *
+     * @param listAttr The attribute to be used as a basis, containing attributes
+     * that may contain placeholders for variables.
+     * @param vars The variables to replace.
+     * @return A new instance of an attribute, whose properties have been
+     * replaced with variables' values.
+     */
+    private static Attribute replaceVarsInListAttribute(ListAttribute listAttr,
+            Object... vars) {
+        Attribute nuattr;
+        ListAttribute nuListAttr = new ListAttribute();
+        nuListAttr.setInherit(listAttr.isInherit());
+        List<Attribute> nuItems = nuListAttr.getValue();
+        for (Object item : listAttr.getValue()) {
+            Attribute child = (Attribute) item;
+            child = replaceVarsInAttribute(child, vars);
+            nuItems.add(child);
+        }
+        nuattr = nuListAttr;
+        return nuattr;
+    }
+
+    /**
+     * Replaces a string with placeholders using values of a variable map.
+     *
+     * @param st The string to replace.
+     * @param vars The variables.
+     * @return The replaced string.
+     */
+    private static String replace(String st, Object... vars) {
+        if (st != null && st.indexOf('{') >= 0) {
+
+            // replace them with markers
+            List<String> originals = new ArrayList<String>();
+            for(Matcher m = INVALID_FORMAT_ELEMENT.matcher(st); m.find() ; m = INVALID_FORMAT_ELEMENT.matcher(st)) {
+                originals.add(m.group());
+                st = m.replaceFirst("INVALID_FORMAT_ELEMENT");
+            }
+
+            // do the MessageFormat replacement (escaping quote characters)
+            st = new MessageFormat(st.replaceAll("'", "'''"), ROOT_LOCALE)
+                    .format(vars, new StringBuffer(), null).toString();
+
+            // return the markers to their original invalid occurrences
+            for (String original : originals) {
+                st = st.replaceFirst("INVALID_FORMAT_ELEMENT", original);
+            }
+        }
+        return st;
+    }
+
+    private static Object[] replaceNullsWithBlank(Object[] varsOrig) {
+        Object[] vars = new Object[varsOrig.length];
+        for(int i = 0; i < varsOrig.length; ++i) {
+            vars[i] = null != varsOrig[i] ? varsOrig[i] : "";
+        }
+        return vars;
+    }
+}
diff --git a/Java/tiles-PatternUtil_169/metadata.json b/Java/tiles-PatternUtil_169/metadata.json
new file mode 100644
index 000000000..47b80b27c
--- /dev/null
+++ b/Java/tiles-PatternUtil_169/metadata.json
@@ -0,0 +1,21 @@
+{
+  "language": "java",
+  "id": "tiles-PatternUtil_169",
+  "buggyPath": ".",
+  "referencePath": null,
+  "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+  "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+  "categories": [
+    "safety",
+    "npe"
+  ],
+  "npe": {
+    "filepath": "tiles-core/src/main/java/org/apache/tiles/definition/pattern/PatternUtil.java",
+    "line": 180,
+    "npe_method": "replaceVarsInSimpleAttribute",
+    "deref_field": "expressionObject",
+    "npe_class": "PatternUtil",
+    "repo": "tiles",
+    "bug_id": "PatternUtil_169"
+  }
+}
diff --git a/Java/tiles-PatternUtil_169/npe.json b/Java/tiles-PatternUtil_169/npe.json
new file mode 100644
index 000000000..16fca2e9e
--- /dev/null
+++ b/Java/tiles-PatternUtil_169/npe.json
@@ -0,0 +1,7 @@
+{
+    "filepath": "tiles-core/src/main/java/org/apache/tiles/definition/pattern/PatternUtil.java",
+    "line": 180,
+    "npe_method": "replaceVarsInSimpleAttribute",
+    "deref_field": "expressionObject",
+    "npe_class": "PatternUtil"
+}
\ No newline at end of file
diff --git a/Java/tiles-PatternUtil_85/Dockerfile b/Java/tiles-PatternUtil_85/Dockerfile
new file mode 100644
index 000000000..6bd79b5d5
--- /dev/null
+++ b/Java/tiles-PatternUtil_85/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:tiles
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+    && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+    && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+    && mv /tmp/buggy.java $BUGGY_PATH \
+    && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/tiles-PatternUtil_85/buggy.java b/Java/tiles-PatternUtil_85/buggy.java
new file mode 100644
index 000000000..77cab94cc
--- /dev/null
+++ b/Java/tiles-PatternUtil_85/buggy.java
@@ -0,0 +1,248 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition.pattern;
+
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.tiles.Attribute;
+import org.apache.tiles.Definition;
+import org.apache.tiles.Expression;
+import org.apache.tiles.ListAttribute;
+
+/**
+ * Utilities for pattern matching and substitution.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public final class PatternUtil {
+
+    /**
+     * The root locale. Notice that this is a replacement for Locale.ROOT for
+     * Java 1.6.
+     */
+    private static final Locale ROOT_LOCALE = new Locale("", "");
+
+    /** Pattern to find {.*} occurrences that do not match {[0-9]+} so to prevent MessageFormat from crashing.
+     */
+    private static final Pattern INVALID_FORMAT_ELEMENT = Pattern.compile("\\{[^}0-9]+\\}");
+
+    /**
+     * Private constructor to avoid instantiation.
+     */
+    private PatternUtil() {
+    }
+
+    /**
+     * Creates a definition given its representation with wildcards and
+     * attribute values with placeholders, replacing real values into
+     * placeholders.
+     *
+     * @param d The definition to replace.
+     * @param name The name of the definition to be created.
+     * @param varsOrig The variables to be substituted.
+     * @return The definition that can be rendered.
+     * @since 2.2.0
+     */
+/**
+ * Creates a definition given its representation with wildcards and
+ * attribute values with placeholders, replacing real values into
+ * placeholders.
+ *
+ * @param d
+ * 		The definition to replace.
+ * @param name
+ * 		The name of the definition to be created.
+ * @param varsOrig
+ * 		The variables to be substituted.
+ * @return The definition that can be rendered.
+ * @since 2.2.0
+ */
+public static org.apache.tiles.Definition replacePlaceholders(org.apache.tiles.Definition d, java.lang.String name, java.lang.Object... varsOrig) {
+    java.lang.Object[] vars = org.apache.tiles.definition.pattern.PatternUtil.replaceNullsWithBlank(varsOrig);
+    org.apache.tiles.Definition nudef = new org.apache.tiles.Definition();
+    nudef.setExtends(org.apache.tiles.definition.pattern.PatternUtil.replace(d.getExtends(), vars));
+    nudef.setName(name);
+    nudef.setPreparer(org.apache.tiles.definition.pattern.PatternUtil.replace(d.getPreparer(), vars));
+    org.apache.tiles.Attribute templateAttribute = d.getTemplateAttribute();
+    {
+        nudef.setTemplateAttribute(org.apache.tiles.definition.pattern.PatternUtil.replaceVarsInAttribute(/* NPEX_NULL_EXP */
+        templateAttribute, vars));
+    }
+    java.util.Set<java.lang.String> attributeNames = d.getLocalAttributeNames();
+    if ((attributeNames != null) && (!attributeNames.isEmpty())) {
+        for (java.lang.String attributeName : attributeNames) {
+            org.apache.tiles.Attribute attr = d.getLocalAttribute(attributeName);
+            org.apache.tiles.Attribute nuattr = org.apache.tiles.definition.pattern.PatternUtil.replaceVarsInAttribute(attr, vars);
+            nudef.putAttribute(org.apache.tiles.definition.pattern.PatternUtil.replace(attributeName, vars), nuattr);
+        }
+    }
+    attributeNames = d.getCascadedAttributeNames();
+    if ((attributeNames != null) && (!attributeNames.isEmpty())) {
+        for (java.lang.String attributeName : attributeNames) {
+            org.apache.tiles.Attribute attr = d.getCascadedAttribute(attributeName);
+            org.apache.tiles.Attribute nuattr = org.apache.tiles.definition.pattern.PatternUtil.replaceVarsInAttribute(attr, vars);
+            nudef.putAttribute(org.apache.tiles.definition.pattern.PatternUtil.replace(attributeName, vars), nuattr, true);
+        }
+    }
+    return nudef;
+}
+
+    /**
+     * Creates a new map that contains all the entries of the
+     * <code>defsMap</code> whose keys are contained in <code>keys</code>.
+     *
+     * @param map The map to read.
+     * @param keys The keys to extract.
+     * @param <K> The key of the map.
+     * @param <V> The value of the map.
+     * @return The extracted map.
+     * @since 2.2.1
+     */
+    public static <K, V> Map<K, V> createExtractedMap(Map<K, V> map, Set<K> keys) {
+        Map<K, V> retValue = new LinkedHashMap<K, V>();
+        for (K key : keys) {
+            retValue.put(key, map.get(key));
+        }
+        return retValue;
+    }
+
+    /**
+     * Replaces variables into an attribute.
+     *
+     * @param attr The attribute to be used as a basis, containing placeholders
+     * for variables.
+     * @param vars The variables to replace.
+     * @return A new instance of an attribute, whose properties have been
+     * replaced with variables' values.
+     */
+    private static Attribute replaceVarsInAttribute(Attribute attr,
+            Object... vars) {
+        Attribute nuattr;
+        if (attr instanceof ListAttribute) {
+            nuattr = replaceVarsInListAttribute((ListAttribute) attr, vars);
+        } else {
+            nuattr = replaceVarsInSimpleAttribute(attr, vars);
+        }
+        return nuattr;
+    }
+
+    /**
+     * Replaces variables into a simple (not list) attribute.
+     *
+     * @param attr The attribute to be used as a basis, containing placeholders
+     * for variables.
+     * @param vars The variables to replace.
+     * @return A new instance of an attribute, whose properties have been
+     * replaced with variables' values.
+     */
+    private static Attribute replaceVarsInSimpleAttribute(Attribute attr,
+            Object... vars) {
+        Attribute nuattr;
+        nuattr = new Attribute();
+
+        nuattr.setRole(replace(attr.getRole(), vars));
+        nuattr.setRenderer(attr.getRenderer());
+        Expression expressionObject = attr.getExpressionObject();
+        if (expressionObject != null) {
+            Expression newExpressionObject = Expression
+                    .createExpression(replace(expressionObject.getExpression(), vars), expressionObject.getLanguage());
+            nuattr.setExpressionObject(newExpressionObject);
+        }
+
+        Object value = attr.getValue();
+        if (value instanceof String) {
+            value = replace((String) value, vars);
+        }
+        nuattr.setValue(value);
+        return nuattr;
+    }
+
+    /**
+     * Replaces variables into a list attribute.
+     *
+     * @param listAttr The attribute to be used as a basis, containing attributes
+     * that may contain placeholders for variables.
+     * @param vars The variables to replace.
+     * @return A new instance of an attribute, whose properties have been
+     * replaced with variables' values.
+     */
+    private static Attribute replaceVarsInListAttribute(ListAttribute listAttr,
+            Object... vars) {
+        Attribute nuattr;
+        ListAttribute nuListAttr = new ListAttribute();
+        nuListAttr.setInherit(listAttr.isInherit());
+        List<Attribute> nuItems = nuListAttr.getValue();
+        for (Object item : listAttr.getValue()) {
+            Attribute child = (Attribute) item;
+            child = replaceVarsInAttribute(child, vars);
+            nuItems.add(child);
+        }
+        nuattr = nuListAttr;
+        return nuattr;
+    }
+
+    /**
+     * Replaces a string with placeholders using values of a variable map.
+     *
+     * @param st The string to replace.
+     * @param vars The variables.
+     * @return The replaced string.
+     */
+    private static String replace(String st, Object... vars) {
+        if (st != null && st.indexOf('{') >= 0) {
+
+            // replace them with markers
+            List<String> originals = new ArrayList<String>();
+            for(Matcher m = INVALID_FORMAT_ELEMENT.matcher(st); m.find() ; m = INVALID_FORMAT_ELEMENT.matcher(st)) {
+                originals.add(m.group());
+                st = m.replaceFirst("INVALID_FORMAT_ELEMENT");
+            }
+
+            // do the MessageFormat replacement (escaping quote characters)
+            st = new MessageFormat(st.replaceAll("'", "'''"), ROOT_LOCALE)
+                    .format(vars, new StringBuffer(), null).toString();
+
+            // return the markers to their original invalid occurrences
+            for (String original : originals) {
+                st = st.replaceFirst("INVALID_FORMAT_ELEMENT", original);
+            }
+        }
+        return st;
+    }
+
+    private static Object[] replaceNullsWithBlank(Object[] varsOrig) {
+        Object[] vars = new Object[varsOrig.length];
+        for(int i = 0; i < varsOrig.length; ++i) {
+            vars[i] = null != varsOrig[i] ? varsOrig[i] : "";
+        }
+        return vars;
+    }
+}
diff --git a/Java/tiles-PatternUtil_85/metadata.json b/Java/tiles-PatternUtil_85/metadata.json
new file mode 100644
index 000000000..a5776a00f
--- /dev/null
+++ b/Java/tiles-PatternUtil_85/metadata.json
@@ -0,0 +1,21 @@
+{
+  "language": "java",
+  "id": "tiles-PatternUtil_85",
+  "buggyPath": ".",
+  "referencePath": null,
+  "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+  "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+  "categories": [
+    "safety",
+    "npe"
+  ],
+  "npe": {
+    "filepath": "tiles-core/src/main/java/org/apache/tiles/definition/pattern/PatternUtil.java",
+    "line": 97,
+    "npe_method": "replacePlaceholders",
+    "deref_field": "templateAttribute",
+    "npe_class": "PatternUtil",
+    "repo": "tiles",
+    "bug_id": "PatternUtil_85"
+  }
+}
diff --git a/Java/tiles-PatternUtil_85/npe.json b/Java/tiles-PatternUtil_85/npe.json
new file mode 100644
index 000000000..0f2a83535
--- /dev/null
+++ b/Java/tiles-PatternUtil_85/npe.json
@@ -0,0 +1,7 @@
+{
+    "filepath": "tiles-core/src/main/java/org/apache/tiles/definition/pattern/PatternUtil.java",
+    "line": 97,
+    "npe_method": "replacePlaceholders",
+    "deref_field": "templateAttribute",
+    "npe_class": "PatternUtil"
+}
\ No newline at end of file
diff --git a/Java/tiles-ResolvingLocaleUrlDefinitionDAO_140/Dockerfile b/Java/tiles-ResolvingLocaleUrlDefinitionDAO_140/Dockerfile
new file mode 100644
index 000000000..6bd79b5d5
--- /dev/null
+++ b/Java/tiles-ResolvingLocaleUrlDefinitionDAO_140/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:tiles
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+    && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+    && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+    && mv /tmp/buggy.java $BUGGY_PATH \
+    && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/tiles-ResolvingLocaleUrlDefinitionDAO_140/buggy.java b/Java/tiles-ResolvingLocaleUrlDefinitionDAO_140/buggy.java
new file mode 100644
index 000000000..71d5955d9
--- /dev/null
+++ b/Java/tiles-ResolvingLocaleUrlDefinitionDAO_140/buggy.java
@@ -0,0 +1,182 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition.dao;
+
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.tiles.Definition;
+import org.apache.tiles.definition.NoSuchDefinitionException;
+import org.apache.tiles.request.ApplicationContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * <p>
+ * A definitions DAO (loading URLs and using Locale as a customization key) that
+ * caches definitions that have been loaded and resolves inheritances.
+ * </p>
+ * <p>
+ * It can check if the URLs change, but by default this feature is turned off.
+ * </p>
+ *
+ * @version $Rev$ $Date$
+ * @since 2.1.0
+ */
+public class ResolvingLocaleUrlDefinitionDAO extends
+        CachingLocaleUrlDefinitionDAO {
+
+    /**
+     * The logging object.
+     */
+    private final Logger log = LoggerFactory.getLogger(ResolvingLocaleUrlDefinitionDAO.class);
+
+    public ResolvingLocaleUrlDefinitionDAO(ApplicationContext applicationContext) {
+        super(applicationContext);
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected Map<String, Definition> loadParentDefinitions(Locale parentLocale) {
+        return loadRawDefinitionsFromResources(parentLocale);
+    }
+
+    @Override
+    protected Map<String, Definition> loadDefinitions(Locale customizationKey) {
+        Map<String, Definition> localeDefsMap = super.loadDefinitions(customizationKey);
+        Map<String, Definition> defsMap = definitionResolver
+                .storeDefinitionPatterns(copyDefinitionMap(localeDefsMap),
+                        customizationKey);
+        resolveInheritances(defsMap, customizationKey);
+        locale2definitionMap.put(customizationKey, defsMap);
+        return defsMap;
+    }
+
+    /** {@inheritDoc} */
+    @Override
+    protected Definition getDefinitionFromResolver(String name,
+            Locale customizationKey) {
+        Definition retValue = super.getDefinitionFromResolver(name, customizationKey);
+        if (retValue != null && retValue.getExtends() != null) {
+            Definition parent = getDefinition(retValue.getExtends(), customizationKey);
+            retValue.inherit(parent);
+        }
+
+        return retValue;
+    }
+
+    /**
+     * Resolve locale-specific extended instances.
+     *
+     * @param map The definition map containing the definitions to resolve.
+     * @param locale The locale to use.
+     * @throws NoSuchDefinitionException If a parent definition is not found.
+     * @since 2.1.0
+     */
+    protected void resolveInheritances(Map<String, Definition> map, Locale locale) {
+        if (map != null) {
+            Set<String> alreadyResolvedDefinitions = new HashSet<String>();
+            for (Definition definition : map.values()) {
+                resolveInheritance(definition, map, locale,
+                        alreadyResolvedDefinitions);
+            }  // end loop
+        }
+    }
+
+    /**
+     * Resolve locale-specific inheritance. First, resolve parent's inheritance,
+     * then set template to the parent's template. Also copy attributes setted
+     * in parent, and not set in child If instance doesn't extend anything, do
+     * nothing.
+     *
+     * @param definition The definition to resolve
+     * @param definitions The definitions to take when obtaining a parent
+     * definition.
+     * @param locale The locale to use.
+     * @param alreadyResolvedDefinitions The set of the definitions that have
+     * been already resolved.
+     * @throws NoSuchDefinitionException If an inheritance can not be solved.
+     * @since 2.1.0
+     */
+/**
+ * Resolve locale-specific inheritance. First, resolve parent's inheritance,
+ * then set template to the parent's template. Also copy attributes setted
+ * in parent, and not set in child If instance doesn't extend anything, do
+ * nothing.
+ *
+ * @param definition
+ * 		The definition to resolve
+ * @param definitions
+ * 		The definitions to take when obtaining a parent
+ * 		definition.
+ * @param locale
+ * 		The locale to use.
+ * @param alreadyResolvedDefinitions
+ * 		The set of the definitions that have
+ * 		been already resolved.
+ * @throws NoSuchDefinitionException
+ * 		If an inheritance can not be solved.
+ * @since 2.1.0
+ */
+protected void resolveInheritance(org.apache.tiles.Definition definition, java.util.Map<java.lang.String, org.apache.tiles.Definition> definitions, java.util.Locale locale, java.util.Set<java.lang.String> alreadyResolvedDefinitions) {
+    // Already done, or not needed ?
+    if ((!definition.isExtending()) || alreadyResolvedDefinitions.contains(definition.getName())) {
+        return;
+    }
+    log.debug("Resolve definition for child name='{}' extends='{}.", definition.getName(), definition.getExtends());
+    // Set as visited to avoid endless recursivity.
+    alreadyResolvedDefinitions.add(definition.getName());
+    // Resolve parent before itself.
+    org.apache.tiles.Definition parent = definitions.get(definition.getExtends());
+    {
+        resolveInheritance(/* NPEX_NULL_EXP */
+        parent, definitions, locale, alreadyResolvedDefinitions);
+        definition.inherit(parent);
+    }
+}
+
+    /**
+     * Copies the definition map to be passed to a higher level of customization
+     * key.
+     *
+     * @param localeDefsMap The map of definition to be copied.
+     * @return The copy of the definition map. This particular implementation
+     * deep-copies the <code>localeDefsMap</code> into a {@link LinkedHashMap}.
+     * @since 2.1.4
+     */
+    @Override
+    protected Map<String, Definition> copyDefinitionMap(
+            Map<String, Definition> localeDefsMap) {
+        Map<String, Definition> retValue = new LinkedHashMap<String, Definition>(
+                localeDefsMap.size());
+
+        for (Map.Entry<String, Definition> entry : localeDefsMap.entrySet()) {
+            Definition definition = new Definition(entry.getValue());
+            retValue.put(entry.getKey(), definition);
+        }
+
+        return retValue;
+    }
+}
diff --git a/Java/tiles-ResolvingLocaleUrlDefinitionDAO_140/metadata.json b/Java/tiles-ResolvingLocaleUrlDefinitionDAO_140/metadata.json
new file mode 100644
index 000000000..8368e72d5
--- /dev/null
+++ b/Java/tiles-ResolvingLocaleUrlDefinitionDAO_140/metadata.json
@@ -0,0 +1,21 @@
+{
+  "language": "java",
+  "id": "tiles-ResolvingLocaleUrlDefinitionDAO_140",
+  "buggyPath": ".",
+  "referencePath": null,
+  "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+  "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+  "categories": [
+    "safety",
+    "npe"
+  ],
+  "npe": {
+    "filepath": "tiles-core/src/main/java/org/apache/tiles/definition/dao/ResolvingLocaleUrlDefinitionDAO.java",
+    "line": 155,
+    "npe_method": "resolveInheritance",
+    "deref_field": "parent",
+    "npe_class": "ResolvingLocaleUrlDefinitionDAO",
+    "repo": "tiles",
+    "bug_id": "ResolvingLocaleUrlDefinitionDAO_140"
+  }
+}
diff --git a/Java/tiles-ResolvingLocaleUrlDefinitionDAO_140/npe.json b/Java/tiles-ResolvingLocaleUrlDefinitionDAO_140/npe.json
new file mode 100644
index 000000000..f86bdc792
--- /dev/null
+++ b/Java/tiles-ResolvingLocaleUrlDefinitionDAO_140/npe.json
@@ -0,0 +1,7 @@
+{
+    "filepath": "tiles-core/src/main/java/org/apache/tiles/definition/dao/ResolvingLocaleUrlDefinitionDAO.java",
+    "line": 155,
+    "npe_method": "resolveInheritance",
+    "deref_field": "parent",
+    "npe_class": "ResolvingLocaleUrlDefinitionDAO"
+}
\ No newline at end of file
diff --git a/Java/tiles-TilesAccess_138/Dockerfile b/Java/tiles-TilesAccess_138/Dockerfile
new file mode 100644
index 000000000..6bd79b5d5
--- /dev/null
+++ b/Java/tiles-TilesAccess_138/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:tiles
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+    && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+    && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+    && mv /tmp/buggy.java $BUGGY_PATH \
+    && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/tiles-TilesAccess_138/buggy.java b/Java/tiles-TilesAccess_138/buggy.java
new file mode 100644
index 000000000..cbea4994a
--- /dev/null
+++ b/Java/tiles-TilesAccess_138/buggy.java
@@ -0,0 +1,186 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.access;
+
+import java.util.Map;
+
+import org.apache.tiles.NoSuchContainerException;
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.Request;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Provides static access to the tiles container.
+ *
+ * @version $Rev$ $Date$
+ */
+public final class TilesAccess {
+
+    /**
+     * Name of the attribute used to store the current used container.
+     */
+    public static final String CURRENT_CONTAINER_ATTRIBUTE_NAME =
+        "org.apache.tiles.servlet.context.ServletTilesRequestContext.CURRENT_CONTAINER_KEY";
+
+    /**
+     * Constructor, private to avoid instantiation.
+     */
+    private TilesAccess() {
+    }
+
+    /**
+     * The name of the attribute to use when getting and setting the container
+     * object in a context.
+     */
+    public static final String CONTAINER_ATTRIBUTE =
+        "org.apache.tiles.CONTAINER";
+
+    /**
+     * Configures the default container to be used in the application.
+     *
+     * @param context The Tiles application context object to use.
+     * @param container The container object to set.
+     * @since 2.1.2
+     */
+    public static void setContainer(ApplicationContext context,
+            TilesContainer container) {
+        setContainer(context, container, CONTAINER_ATTRIBUTE);
+    }
+
+    /**
+     * Configures the container to be used in the application.
+     *
+     * @param context The Tiles application context object to use.
+     * @param container The container object to set.
+     * @param key The key under which the container will be stored.
+     * @since 2.1.2
+     */
+    public static void setContainer(ApplicationContext context,
+            TilesContainer container, String key) {
+        Logger log = LoggerFactory.getLogger(TilesAccess.class);
+        if (key == null) {
+            key = CONTAINER_ATTRIBUTE;
+        }
+
+        if (container == null) {
+            if (log.isInfoEnabled()) {
+                log.info("Removing TilesContext for context: " + context.getClass().getName());
+            }
+            context.getApplicationScope().remove(key);
+        } else {
+            if (log.isInfoEnabled()) {
+                log.info("Publishing TilesContext for context: " + context.getClass().getName());
+            }
+            context.getApplicationScope().put(key, container);
+        }
+    }
+
+    /**
+     * Returns default the container to be used in the application.
+     *
+     * @param context The Tiles application context object to use.
+     * @return The default container object.
+     * @since 3.0.0
+     */
+    public static TilesContainer getContainer(ApplicationContext context) {
+        return getContainer(context, CONTAINER_ATTRIBUTE);
+    }
+
+    /**
+     * Returns the container to be used in the application registered under a specific key.
+     *
+     * @param context The Tiles application context object to use.
+     * @param key The key under which the container will be stored.
+     * @return The container object.
+     * @since 3.0.0
+     */
+    public static TilesContainer getContainer(ApplicationContext context,
+            String key) {
+        if (key == null) {
+            key = CONTAINER_ATTRIBUTE;
+        }
+
+        return (TilesContainer) context.getApplicationScope().get(key);
+    }
+
+    /**
+     * Sets the current container to use in web pages.
+     *
+     * @param request The request to use.
+     * @param key The key under which the container is stored.
+     * @since 2.1.0
+     */
+/**
+ * Sets the current container to use in web pages.
+ *
+ * @param request
+ * 		The request to use.
+ * @param key
+ * 		The key under which the container is stored.
+ * @since 2.1.0
+ */
+public static void setCurrentContainer(org.apache.tiles.request.Request request, java.lang.String key) {
+    org.apache.tiles.request.ApplicationContext applicationContext = request.getApplicationContext();
+    org.apache.tiles.TilesContainer container = org.apache.tiles.access.TilesAccess.getContainer(applicationContext, key);
+    {
+        request.getContext("request").put(org.apache.tiles.access.TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME, /* NPEX_NULL_EXP */
+        container);
+    }
+}
+
+    /**
+     * Sets the current container to use in web pages.
+     *
+     * @param request The request to use.
+     * @param container The container to use as the current container.
+     * @since 2.1.0
+     */
+    public static void setCurrentContainer(Request request,
+            TilesContainer container) {
+        if (container != null) {
+            request.getContext("request").put(CURRENT_CONTAINER_ATTRIBUTE_NAME, container);
+        } else {
+            throw new NullPointerException("The container cannot be null");
+        }
+    }
+
+    /**
+     * Returns the current container that has been set, or the default one.
+     *
+     * @param request The request to use.
+     * @return The current Tiles container to use in web pages.
+     * @since 2.1.0
+     */
+    public static TilesContainer getCurrentContainer(Request request) {
+        ApplicationContext context = request.getApplicationContext();
+        Map<String, Object> requestScope = request.getContext("request");
+        TilesContainer container = (TilesContainer) requestScope.get(CURRENT_CONTAINER_ATTRIBUTE_NAME);
+        if (container == null) {
+            container = getContainer(context);
+            requestScope.put(CURRENT_CONTAINER_ATTRIBUTE_NAME, container);
+        }
+
+        return container;
+    }
+}
diff --git a/Java/tiles-TilesAccess_138/metadata.json b/Java/tiles-TilesAccess_138/metadata.json
new file mode 100644
index 000000000..fb1e5555c
--- /dev/null
+++ b/Java/tiles-TilesAccess_138/metadata.json
@@ -0,0 +1,21 @@
+{
+  "language": "java",
+  "id": "tiles-TilesAccess_138",
+  "buggyPath": ".",
+  "referencePath": null,
+  "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+  "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+  "categories": [
+    "safety",
+    "npe"
+  ],
+  "npe": {
+    "filepath": "tiles-api/src/main/java/org/apache/tiles/access/TilesAccess.java",
+    "line": 148,
+    "npe_method": "setCurrentContainer",
+    "deref_field": "container",
+    "npe_class": "TilesAccess",
+    "repo": "tiles",
+    "bug_id": "TilesAccess_138"
+  }
+}
diff --git a/Java/tiles-TilesAccess_138/npe.json b/Java/tiles-TilesAccess_138/npe.json
new file mode 100644
index 000000000..565938cfc
--- /dev/null
+++ b/Java/tiles-TilesAccess_138/npe.json
@@ -0,0 +1,7 @@
+{
+    "filepath": "tiles-api/src/main/java/org/apache/tiles/access/TilesAccess.java",
+    "line": 148,
+    "npe_method": "setCurrentContainer",
+    "deref_field": "container",
+    "npe_class": "TilesAccess"
+}
\ No newline at end of file
diff --git a/Java/tiles-TilesAccess_155/Dockerfile b/Java/tiles-TilesAccess_155/Dockerfile
new file mode 100644
index 000000000..6bd79b5d5
--- /dev/null
+++ b/Java/tiles-TilesAccess_155/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:tiles
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+    && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+    && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+    && mv /tmp/buggy.java $BUGGY_PATH \
+    && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/tiles-TilesAccess_155/buggy.java b/Java/tiles-TilesAccess_155/buggy.java
new file mode 100644
index 000000000..cb9036ba7
--- /dev/null
+++ b/Java/tiles-TilesAccess_155/buggy.java
@@ -0,0 +1,187 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.access;
+
+import java.util.Map;
+
+import org.apache.tiles.NoSuchContainerException;
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.Request;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Provides static access to the tiles container.
+ *
+ * @version $Rev$ $Date$
+ */
+public final class TilesAccess {
+
+    /**
+     * Name of the attribute used to store the current used container.
+     */
+    public static final String CURRENT_CONTAINER_ATTRIBUTE_NAME =
+        "org.apache.tiles.servlet.context.ServletTilesRequestContext.CURRENT_CONTAINER_KEY";
+
+    /**
+     * Constructor, private to avoid instantiation.
+     */
+    private TilesAccess() {
+    }
+
+    /**
+     * The name of the attribute to use when getting and setting the container
+     * object in a context.
+     */
+    public static final String CONTAINER_ATTRIBUTE =
+        "org.apache.tiles.CONTAINER";
+
+    /**
+     * Configures the default container to be used in the application.
+     *
+     * @param context The Tiles application context object to use.
+     * @param container The container object to set.
+     * @since 2.1.2
+     */
+    public static void setContainer(ApplicationContext context,
+            TilesContainer container) {
+        setContainer(context, container, CONTAINER_ATTRIBUTE);
+    }
+
+    /**
+     * Configures the container to be used in the application.
+     *
+     * @param context The Tiles application context object to use.
+     * @param container The container object to set.
+     * @param key The key under which the container will be stored.
+     * @since 2.1.2
+     */
+    public static void setContainer(ApplicationContext context,
+            TilesContainer container, String key) {
+        Logger log = LoggerFactory.getLogger(TilesAccess.class);
+        if (key == null) {
+            key = CONTAINER_ATTRIBUTE;
+        }
+
+        if (container == null) {
+            if (log.isInfoEnabled()) {
+                log.info("Removing TilesContext for context: " + context.getClass().getName());
+            }
+            context.getApplicationScope().remove(key);
+        } else {
+            if (log.isInfoEnabled()) {
+                log.info("Publishing TilesContext for context: " + context.getClass().getName());
+            }
+            context.getApplicationScope().put(key, container);
+        }
+    }
+
+    /**
+     * Returns default the container to be used in the application.
+     *
+     * @param context The Tiles application context object to use.
+     * @return The default container object.
+     * @since 3.0.0
+     */
+    public static TilesContainer getContainer(ApplicationContext context) {
+        return getContainer(context, CONTAINER_ATTRIBUTE);
+    }
+
+    /**
+     * Returns the container to be used in the application registered under a specific key.
+     *
+     * @param context The Tiles application context object to use.
+     * @param key The key under which the container will be stored.
+     * @return The container object.
+     * @since 3.0.0
+     */
+    public static TilesContainer getContainer(ApplicationContext context,
+            String key) {
+        if (key == null) {
+            key = CONTAINER_ATTRIBUTE;
+        }
+
+        return (TilesContainer) context.getApplicationScope().get(key);
+    }
+
+    /**
+     * Sets the current container to use in web pages.
+     *
+     * @param request The request to use.
+     * @param key The key under which the container is stored.
+     * @since 2.1.0
+     */
+    public static void setCurrentContainer(Request request,
+            String key) {
+        ApplicationContext applicationContext = request.getApplicationContext();
+        TilesContainer container = getContainer(applicationContext, key);
+        if (container != null) {
+            request.getContext("request").put(CURRENT_CONTAINER_ATTRIBUTE_NAME, container);
+        } else {
+            throw new NoSuchContainerException("The container with the key '"
+                    + key + "' cannot be found");
+        }
+    }
+
+    /**
+     * Sets the current container to use in web pages.
+     *
+     * @param request The request to use.
+     * @param container The container to use as the current container.
+     * @since 2.1.0
+     */
+/**
+ * Sets the current container to use in web pages.
+ *
+ * @param request
+ * 		The request to use.
+ * @param container
+ * 		The container to use as the current container.
+ * @since 2.1.0
+ */
+public static void setCurrentContainer(org.apache.tiles.request.Request request, org.apache.tiles.TilesContainer container) {
+    {
+        request.getContext("request").put(org.apache.tiles.access.TilesAccess.CURRENT_CONTAINER_ATTRIBUTE_NAME, /* NPEX_NULL_EXP */
+        container);
+    }
+}
+
+    /**
+     * Returns the current container that has been set, or the default one.
+     *
+     * @param request The request to use.
+     * @return The current Tiles container to use in web pages.
+     * @since 2.1.0
+     */
+    public static TilesContainer getCurrentContainer(Request request) {
+        ApplicationContext context = request.getApplicationContext();
+        Map<String, Object> requestScope = request.getContext("request");
+        TilesContainer container = (TilesContainer) requestScope.get(CURRENT_CONTAINER_ATTRIBUTE_NAME);
+        if (container == null) {
+            container = getContainer(context);
+            requestScope.put(CURRENT_CONTAINER_ATTRIBUTE_NAME, container);
+        }
+
+        return container;
+    }
+}
diff --git a/Java/tiles-TilesAccess_155/metadata.json b/Java/tiles-TilesAccess_155/metadata.json
new file mode 100644
index 000000000..d5c9dd7cf
--- /dev/null
+++ b/Java/tiles-TilesAccess_155/metadata.json
@@ -0,0 +1,21 @@
+{
+  "language": "java",
+  "id": "tiles-TilesAccess_155",
+  "buggyPath": ".",
+  "referencePath": null,
+  "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+  "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+  "categories": [
+    "safety",
+    "npe"
+  ],
+  "npe": {
+    "filepath": "tiles-api/src/main/java/org/apache/tiles/access/TilesAccess.java",
+    "line": 165,
+    "npe_method": "setCurrentContainer",
+    "deref_field": "container",
+    "npe_class": "TilesAccess",
+    "repo": "tiles",
+    "bug_id": "TilesAccess_155"
+  }
+}
diff --git a/Java/tiles-TilesAccess_155/npe.json b/Java/tiles-TilesAccess_155/npe.json
new file mode 100644
index 000000000..49e4852ef
--- /dev/null
+++ b/Java/tiles-TilesAccess_155/npe.json
@@ -0,0 +1,7 @@
+{
+    "filepath": "tiles-api/src/main/java/org/apache/tiles/access/TilesAccess.java",
+    "line": 165,
+    "npe_method": "setCurrentContainer",
+    "deref_field": "container",
+    "npe_class": "TilesAccess"
+}
\ No newline at end of file
diff --git a/Java/tiles-TilesAccess_86/Dockerfile b/Java/tiles-TilesAccess_86/Dockerfile
new file mode 100644
index 000000000..6bd79b5d5
--- /dev/null
+++ b/Java/tiles-TilesAccess_86/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:tiles
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+    && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+    && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+    && mv /tmp/buggy.java $BUGGY_PATH \
+    && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/tiles-TilesAccess_86/buggy.java b/Java/tiles-TilesAccess_86/buggy.java
new file mode 100644
index 000000000..e90d47637
--- /dev/null
+++ b/Java/tiles-TilesAccess_86/buggy.java
@@ -0,0 +1,185 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.access;
+
+import java.util.Map;
+
+import org.apache.tiles.NoSuchContainerException;
+import org.apache.tiles.TilesContainer;
+import org.apache.tiles.request.ApplicationContext;
+import org.apache.tiles.request.Request;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Provides static access to the tiles container.
+ *
+ * @version $Rev$ $Date$
+ */
+public final class TilesAccess {
+
+    /**
+     * Name of the attribute used to store the current used container.
+     */
+    public static final String CURRENT_CONTAINER_ATTRIBUTE_NAME =
+        "org.apache.tiles.servlet.context.ServletTilesRequestContext.CURRENT_CONTAINER_KEY";
+
+    /**
+     * Constructor, private to avoid instantiation.
+     */
+    private TilesAccess() {
+    }
+
+    /**
+     * The name of the attribute to use when getting and setting the container
+     * object in a context.
+     */
+    public static final String CONTAINER_ATTRIBUTE =
+        "org.apache.tiles.CONTAINER";
+
+    /**
+     * Configures the default container to be used in the application.
+     *
+     * @param context The Tiles application context object to use.
+     * @param container The container object to set.
+     * @since 2.1.2
+     */
+    public static void setContainer(ApplicationContext context,
+            TilesContainer container) {
+        setContainer(context, container, CONTAINER_ATTRIBUTE);
+    }
+
+    /**
+     * Configures the container to be used in the application.
+     *
+     * @param context The Tiles application context object to use.
+     * @param container The container object to set.
+     * @param key The key under which the container will be stored.
+     * @since 2.1.2
+     */
+/**
+ * Configures the container to be used in the application.
+ *
+ * @param context
+ * 		The Tiles application context object to use.
+ * @param container
+ * 		The container object to set.
+ * @param key
+ * 		The key under which the container will be stored.
+ * @since 2.1.2
+ */
+public static void setContainer(org.apache.tiles.request.ApplicationContext context, org.apache.tiles.TilesContainer container, java.lang.String key) {
+    org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(org.apache.tiles.access.TilesAccess.class);
+    if (key == null) {
+        key = org.apache.tiles.access.TilesAccess.CONTAINER_ATTRIBUTE;
+    }
+    {
+        if (log.isInfoEnabled()) {
+            log.info("Publishing TilesContext for context: " + context.getClass().getName());
+        }
+        context.getApplicationScope().put(key, /* NPEX_NULL_EXP */
+        container);
+    }
+}
+
+    /**
+     * Returns default the container to be used in the application.
+     *
+     * @param context The Tiles application context object to use.
+     * @return The default container object.
+     * @since 3.0.0
+     */
+    public static TilesContainer getContainer(ApplicationContext context) {
+        return getContainer(context, CONTAINER_ATTRIBUTE);
+    }
+
+    /**
+     * Returns the container to be used in the application registered under a specific key.
+     *
+     * @param context The Tiles application context object to use.
+     * @param key The key under which the container will be stored.
+     * @return The container object.
+     * @since 3.0.0
+     */
+    public static TilesContainer getContainer(ApplicationContext context,
+            String key) {
+        if (key == null) {
+            key = CONTAINER_ATTRIBUTE;
+        }
+
+        return (TilesContainer) context.getApplicationScope().get(key);
+    }
+
+    /**
+     * Sets the current container to use in web pages.
+     *
+     * @param request The request to use.
+     * @param key The key under which the container is stored.
+     * @since 2.1.0
+     */
+    public static void setCurrentContainer(Request request,
+            String key) {
+        ApplicationContext applicationContext = request.getApplicationContext();
+        TilesContainer container = getContainer(applicationContext, key);
+        if (container != null) {
+            request.getContext("request").put(CURRENT_CONTAINER_ATTRIBUTE_NAME, container);
+        } else {
+            throw new NoSuchContainerException("The container with the key '"
+                    + key + "' cannot be found");
+        }
+    }
+
+    /**
+     * Sets the current container to use in web pages.
+     *
+     * @param request The request to use.
+     * @param container The container to use as the current container.
+     * @since 2.1.0
+     */
+    public static void setCurrentContainer(Request request,
+            TilesContainer container) {
+        if (container != null) {
+            request.getContext("request").put(CURRENT_CONTAINER_ATTRIBUTE_NAME, container);
+        } else {
+            throw new NullPointerException("The container cannot be null");
+        }
+    }
+
+    /**
+     * Returns the current container that has been set, or the default one.
+     *
+     * @param request The request to use.
+     * @return The current Tiles container to use in web pages.
+     * @since 2.1.0
+     */
+    public static TilesContainer getCurrentContainer(Request request) {
+        ApplicationContext context = request.getApplicationContext();
+        Map<String, Object> requestScope = request.getContext("request");
+        TilesContainer container = (TilesContainer) requestScope.get(CURRENT_CONTAINER_ATTRIBUTE_NAME);
+        if (container == null) {
+            container = getContainer(context);
+            requestScope.put(CURRENT_CONTAINER_ATTRIBUTE_NAME, container);
+        }
+
+        return container;
+    }
+}
diff --git a/Java/tiles-TilesAccess_86/metadata.json b/Java/tiles-TilesAccess_86/metadata.json
new file mode 100644
index 000000000..92e8953de
--- /dev/null
+++ b/Java/tiles-TilesAccess_86/metadata.json
@@ -0,0 +1,21 @@
+{
+  "language": "java",
+  "id": "tiles-TilesAccess_86",
+  "buggyPath": ".",
+  "referencePath": null,
+  "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+  "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+  "categories": [
+    "safety",
+    "npe"
+  ],
+  "npe": {
+    "filepath": "tiles-api/src/main/java/org/apache/tiles/access/TilesAccess.java",
+    "line": 100,
+    "npe_method": "setContainer",
+    "deref_field": "container",
+    "npe_class": "TilesAccess",
+    "repo": "tiles",
+    "bug_id": "TilesAccess_86"
+  }
+}
diff --git a/Java/tiles-TilesAccess_86/npe.json b/Java/tiles-TilesAccess_86/npe.json
new file mode 100644
index 000000000..4426bf994
--- /dev/null
+++ b/Java/tiles-TilesAccess_86/npe.json
@@ -0,0 +1,7 @@
+{
+    "filepath": "tiles-api/src/main/java/org/apache/tiles/access/TilesAccess.java",
+    "line": 100,
+    "npe_method": "setContainer",
+    "deref_field": "container",
+    "npe_class": "TilesAccess"
+}
\ No newline at end of file
diff --git a/Java/tiles-WildcardDefinitionPatternMatcher_77/Dockerfile b/Java/tiles-WildcardDefinitionPatternMatcher_77/Dockerfile
new file mode 100644
index 000000000..6bd79b5d5
--- /dev/null
+++ b/Java/tiles-WildcardDefinitionPatternMatcher_77/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:tiles
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+    && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+    && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+    && mv /tmp/buggy.java $BUGGY_PATH \
+    && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/tiles-WildcardDefinitionPatternMatcher_77/buggy.java b/Java/tiles-WildcardDefinitionPatternMatcher_77/buggy.java
new file mode 100644
index 000000000..79aea7f94
--- /dev/null
+++ b/Java/tiles-WildcardDefinitionPatternMatcher_77/buggy.java
@@ -0,0 +1,85 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.tiles.definition.pattern.wildcard;
+
+import java.util.List;
+
+import org.apache.tiles.Definition;
+import org.apache.tiles.definition.pattern.DefinitionPatternMatcher;
+import org.apache.tiles.definition.pattern.PatternUtil;
+import org.apache.tiles.util.WildcardHelper;
+
+/**
+ * Matches wildcard patterns in definitions.
+ *
+ * @version $Rev$ $Date$
+ * @since 2.2.0
+ */
+public class WildcardDefinitionPatternMatcher implements
+        DefinitionPatternMatcher {
+
+    /**
+     * Allows to parse wildcard expressions and to recognize substitution
+     * variables.
+     */
+    private WildcardHelper wildcardHelper;
+
+    /**
+     * The definition to use as a basis.
+     */
+    private Definition definition;
+
+    /**
+     * The pattern to use.
+     */
+    private int[] pattern;
+
+    /**
+     * Constructor.
+     *
+     * @param pattern The pattern to use, in string form.
+     * @param definition The definition to use as a basis.
+     * @param wildcardHelper The object that parses wildcard expressions and
+     * recognized substitution variables.
+     * @since 2.2.0
+     */
+    public WildcardDefinitionPatternMatcher(String pattern,
+            Definition definition, WildcardHelper wildcardHelper) {
+        this.wildcardHelper = wildcardHelper;
+        this.definition = definition;
+        this.pattern = wildcardHelper.compilePattern(pattern);
+    }
+
+    /** {@inheritDoc} */
+/**
+ * {@inheritDoc }
+ */
+public org.apache.tiles.Definition createDefinition(java.lang.String definitionName) {
+    java.util.List<java.lang.String> vars = wildcardHelper.match(definitionName, pattern);
+    org.apache.tiles.Definition d = null;
+    {
+        d = org.apache.tiles.definition.pattern.PatternUtil.replacePlaceholders(definition, definitionName, /* NPEX_NULL_EXP */
+        vars.toArray());
+    }
+    return d;
+}
+}
diff --git a/Java/tiles-WildcardDefinitionPatternMatcher_77/metadata.json b/Java/tiles-WildcardDefinitionPatternMatcher_77/metadata.json
new file mode 100644
index 000000000..893aec127
--- /dev/null
+++ b/Java/tiles-WildcardDefinitionPatternMatcher_77/metadata.json
@@ -0,0 +1,21 @@
+{
+  "language": "java",
+  "id": "tiles-WildcardDefinitionPatternMatcher_77",
+  "buggyPath": ".",
+  "referencePath": null,
+  "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+  "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+  "categories": [
+    "safety",
+    "npe"
+  ],
+  "npe": {
+    "filepath": "tiles-core/src/main/java/org/apache/tiles/definition/pattern/wildcard/WildcardDefinitionPatternMatcher.java",
+    "line": 81,
+    "npe_method": "createDefinition",
+    "deref_field": "vars",
+    "npe_class": "WildcardDefinitionPatternMatcher",
+    "repo": "tiles",
+    "bug_id": "WildcardDefinitionPatternMatcher_77"
+  }
+}
diff --git a/Java/tiles-WildcardDefinitionPatternMatcher_77/npe.json b/Java/tiles-WildcardDefinitionPatternMatcher_77/npe.json
new file mode 100644
index 000000000..faa71efb8
--- /dev/null
+++ b/Java/tiles-WildcardDefinitionPatternMatcher_77/npe.json
@@ -0,0 +1,7 @@
+{
+    "filepath": "tiles-core/src/main/java/org/apache/tiles/definition/pattern/wildcard/WildcardDefinitionPatternMatcher.java",
+    "line": 81,
+    "npe_method": "createDefinition",
+    "deref_field": "vars",
+    "npe_class": "WildcardDefinitionPatternMatcher"
+}
\ No newline at end of file
diff --git a/Java/tiles-autotag-QDoxTemplateSuiteFactory_143/Dockerfile b/Java/tiles-autotag-QDoxTemplateSuiteFactory_143/Dockerfile
new file mode 100644
index 000000000..fc34ed72c
--- /dev/null
+++ b/Java/tiles-autotag-QDoxTemplateSuiteFactory_143/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:tiles-autotag
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+    && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+    && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+    && mv /tmp/buggy.java $BUGGY_PATH \
+    && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/tiles-autotag-QDoxTemplateSuiteFactory_143/buggy.java b/Java/tiles-autotag-QDoxTemplateSuiteFactory_143/buggy.java
new file mode 100644
index 000000000..58796235f
--- /dev/null
+++ b/Java/tiles-autotag-QDoxTemplateSuiteFactory_143/buggy.java
@@ -0,0 +1,272 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.core;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tiles.autotag.core.runtime.ModelBody;
+import org.apache.tiles.autotag.core.runtime.annotation.Parameter;
+import org.apache.tiles.autotag.model.TemplateClass;
+import org.apache.tiles.autotag.model.TemplateMethod;
+import org.apache.tiles.autotag.model.TemplateParameter;
+import org.apache.tiles.autotag.model.TemplateSuite;
+import org.apache.tiles.autotag.model.TemplateSuiteFactory;
+
+import com.thoughtworks.qdox.JavaDocBuilder;
+import com.thoughtworks.qdox.model.Annotation;
+import com.thoughtworks.qdox.model.DocletTag;
+import com.thoughtworks.qdox.model.JavaClass;
+import com.thoughtworks.qdox.model.JavaMethod;
+import com.thoughtworks.qdox.model.JavaParameter;
+import com.thoughtworks.qdox.model.Type;
+
+/**
+ * Creates a template suite using QDox.
+ *
+ * @version $Rev$ $Date$
+ */
+public class QDoxTemplateSuiteFactory implements TemplateSuiteFactory {
+
+    /**
+     * The suffix of parsed classes.
+     */
+    private static final String TEMPLATE_SUFFIX = "Model";
+
+    /**
+     * The Javadoc builder.
+     */
+    private JavaDocBuilder builder;
+
+    /**
+     * The name of the suite.
+     */
+    private String suiteName;
+
+    /**
+     * The documentation of the suite.
+     */
+    private String suiteDocumentation;
+
+    /**
+     * The request class the suite.
+     */
+    private String requestClass;
+
+    /**
+     * Constructor.
+     *
+     * @param sourceFiles All the source files to parse.
+     */
+    public QDoxTemplateSuiteFactory(File... sourceFiles) {
+        builder = new JavaDocBuilder();
+        try {
+            for (File file : sourceFiles) {
+                builder.addSource(file);
+            }
+        } catch (IOException e) {
+            throw new ClassParseException(
+                    "I/O Exception when adding source files", e);
+        }
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param urls All the URLs of source files to parse.
+     */
+    public QDoxTemplateSuiteFactory(URL... urls) {
+        builder = new JavaDocBuilder();
+        try {
+            for (URL url : urls) {
+                builder.addSource(url);
+            }
+        } catch (IOException e) {
+            throw new ClassParseException(
+                    "I/O Exception when adding source files", e);
+        }
+    }
+
+    /**
+     * Sets the suite name to assign to the created suite.
+     *
+     * @param suiteName The suite name.
+     */
+    public void setSuiteName(String suiteName) {
+        this.suiteName = suiteName;
+    }
+
+    /**
+     * Sets the suite documentation to assign to the suite.
+     *
+     * @param suiteDocumentation The suite documentation.
+     */
+    public void setSuiteDocumentation(String suiteDocumentation) {
+        this.suiteDocumentation = suiteDocumentation;
+    }
+
+    /**
+     * Sets the request class used by the suite.
+     *
+     * @param requestClass The request class name.
+     */
+    public void setRequestClass(String requestClass) {
+        this.requestClass = requestClass;
+    }
+
+    @Override
+public org.apache.tiles.autotag.model.TemplateSuite createTemplateSuite() {
+    java.util.List<org.apache.tiles.autotag.model.TemplateClass> classes = new java.util.ArrayList<org.apache.tiles.autotag.model.TemplateClass>();
+    for (com.thoughtworks.qdox.model.JavaClass clazz : builder.getClasses()) {
+        java.lang.String tagClassPrefix = getTagClassPrefix(clazz);
+        {
+            java.lang.String tagName = /* NPEX_NULL_EXP */
+            tagClassPrefix.substring(0, 1).toLowerCase() + tagClassPrefix.substring(1);
+            org.apache.tiles.autotag.model.TemplateMethod executeMethod = null;
+            for (com.thoughtworks.qdox.model.JavaMethod method : clazz.getMethods()) {
+                if (isFeasible(method)) {
+                    executeMethod = createMethod(method);
+                }
+            }
+            if (executeMethod != null) {
+                org.apache.tiles.autotag.model.TemplateClass templateClass = new org.apache.tiles.autotag.model.TemplateClass(clazz.getFullyQualifiedName(), tagName, tagClassPrefix, executeMethod);
+                templateClass.setDocumentation(clazz.getComment());
+                classes.add(templateClass);
+            }
+        }
+    }
+    return new org.apache.tiles.autotag.model.TemplateSuite(suiteName, suiteDocumentation, classes);
+}
+
+    /**
+     * Computes the tag class prefix.
+     *
+     * @param clazz The parsed class.
+     * @return The tag class prefix.
+     */
+    private String getTagClassPrefix(JavaClass clazz) {
+        String tagName;
+        String simpleClassName = clazz.getName();
+        if (simpleClassName.endsWith(TEMPLATE_SUFFIX)
+                && simpleClassName.length() > TEMPLATE_SUFFIX.length()) {
+            tagName = simpleClassName.substring(0, 1).toUpperCase()
+                    + simpleClassName.substring(1, simpleClassName.length()
+                            - TEMPLATE_SUFFIX.length());
+        } else {
+            tagName = null;
+        }
+        return tagName;
+    }
+
+    /**
+     * Creates a template method descriptor from a parsed method.
+     *
+     * @param method The parsed method.
+     * @return The template method descriptor.
+     */
+    private TemplateMethod createMethod(JavaMethod method) {
+        List<TemplateParameter> params = new ArrayList<TemplateParameter>();
+        for (JavaParameter parameter : method.getParameters()) {
+            String exportedName = parameter.getName();
+            boolean required = false;
+            String defaultValue = null;
+            Annotation[] annotations = parameter.getAnnotations();
+            if (annotations != null && annotations.length > 0) {
+                boolean found = false;
+                for (int i = 0; i < annotations.length && !found; i++) {
+                    if (Parameter.class.getName().equals(annotations[i].getType().getFullyQualifiedName())) {
+                        found = true;
+                        String candidateName = (String) annotations[i].getNamedParameter("name");
+                        if (candidateName != null && candidateName.length() > 2) {
+                            exportedName = candidateName.substring(1, candidateName.length() - 1);
+                        }
+                        required = "true".equals(annotations[i].getNamedParameter("required"));
+                        candidateName = (String) annotations[i].getNamedParameter("defaultValue");
+                        if (candidateName != null && candidateName.length() > 2) {
+                            defaultValue = candidateName.substring(1, candidateName.length() - 1);
+                        }
+                    }
+                }
+            }
+            String parameterType = parameter.getType()
+                    .getFullyQualifiedName();
+            TemplateParameter templateParameter = new TemplateParameter(
+                    parameter.getName(), exportedName, parameterType, defaultValue, required,
+                    requestClass.equals(parameterType));
+            params.add(templateParameter);
+        }
+        TemplateMethod templateMethod = new TemplateMethod(method.getName(),
+                params);
+        templateMethod.setDocumentation(method.getComment());
+        DocletTag[] tags = method.getTagsByName("param");
+        for (DocletTag tag : tags) {
+            String[] tagParams = tag.getParameters();
+            if (tagParams.length > 0) {
+                TemplateParameter templateParameter = templateMethod
+                        .getParameterByName(tagParams[0]);
+                if (templateParameter != null) {
+                    String tagValue = tag.getValue();
+                    int pos = tagValue.indexOf(" ");
+                    templateParameter.setDocumentation(tagValue.substring(pos)
+                            .trim());
+                }
+            }
+        }
+        return templateMethod;
+    }
+
+    /**
+     * Verifies if the method can be used as an "execute" method.
+     *
+     * @param method The parsed method.
+     * @return <code>true</code> if it is an execute method.
+     */
+    private boolean isFeasible(JavaMethod method) {
+        Type returns = method.getReturns();
+        if ("execute".equals(method.getName()) && returns != null
+                && "void".equals(returns.getFullyQualifiedName())
+                && method.isPublic() && !method.isStatic()
+                && !method.isAbstract() && !method.isConstructor()) {
+            JavaParameter[] params = method.getParameters();
+            if (params.length > 0) {
+                JavaParameter param = params[params.length - 1];
+                if (requestClass.equals(
+                        param.getType().getFullyQualifiedName())) {
+                    return true;
+                }
+            }
+            if (params.length >= 2) {
+                JavaParameter param1 = params[params.length - 2];
+                JavaParameter param2 = params[params.length - 1];
+                if (requestClass.equals(
+                        param1.getType().getFullyQualifiedName())
+                        && ModelBody.class.getName().equals(
+                                param2.getType().getFullyQualifiedName())) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+}
diff --git a/Java/tiles-autotag-QDoxTemplateSuiteFactory_143/metadata.json b/Java/tiles-autotag-QDoxTemplateSuiteFactory_143/metadata.json
new file mode 100644
index 000000000..26fa82a2e
--- /dev/null
+++ b/Java/tiles-autotag-QDoxTemplateSuiteFactory_143/metadata.json
@@ -0,0 +1,21 @@
+{
+  "language": "java",
+  "id": "tiles-autotag-QDoxTemplateSuiteFactory_143",
+  "buggyPath": ".",
+  "referencePath": null,
+  "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+  "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+  "categories": [
+    "safety",
+    "npe"
+  ],
+  "npe": {
+    "filepath": "tiles-autotag-core/src/main/java/org/apache/tiles/autotag/core/QDoxTemplateSuiteFactory.java",
+    "line": 145,
+    "npe_method": "createTemplateSuite",
+    "deref_field": "tagClassPrefix",
+    "npe_class": "QDoxTemplateSuiteFactory",
+    "repo": "tiles-autotag",
+    "bug_id": "QDoxTemplateSuiteFactory_143"
+  }
+}
diff --git a/Java/tiles-autotag-QDoxTemplateSuiteFactory_143/npe.json b/Java/tiles-autotag-QDoxTemplateSuiteFactory_143/npe.json
new file mode 100644
index 000000000..d73b44cd2
--- /dev/null
+++ b/Java/tiles-autotag-QDoxTemplateSuiteFactory_143/npe.json
@@ -0,0 +1,7 @@
+{
+    "filepath": "tiles-autotag-core/src/main/java/org/apache/tiles/autotag/core/QDoxTemplateSuiteFactory.java",
+    "line": 145,
+    "npe_method": "createTemplateSuite",
+    "deref_field": "tagClassPrefix",
+    "npe_class": "QDoxTemplateSuiteFactory"
+}
\ No newline at end of file
diff --git a/Java/tiles-autotag-QDoxTemplateSuiteFactory_152/Dockerfile b/Java/tiles-autotag-QDoxTemplateSuiteFactory_152/Dockerfile
new file mode 100644
index 000000000..fc34ed72c
--- /dev/null
+++ b/Java/tiles-autotag-QDoxTemplateSuiteFactory_152/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:tiles-autotag
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+    && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+    && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+    && mv /tmp/buggy.java $BUGGY_PATH \
+    && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/tiles-autotag-QDoxTemplateSuiteFactory_152/buggy.java b/Java/tiles-autotag-QDoxTemplateSuiteFactory_152/buggy.java
new file mode 100644
index 000000000..03852fb55
--- /dev/null
+++ b/Java/tiles-autotag-QDoxTemplateSuiteFactory_152/buggy.java
@@ -0,0 +1,272 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.core;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.tiles.autotag.core.runtime.ModelBody;
+import org.apache.tiles.autotag.core.runtime.annotation.Parameter;
+import org.apache.tiles.autotag.model.TemplateClass;
+import org.apache.tiles.autotag.model.TemplateMethod;
+import org.apache.tiles.autotag.model.TemplateParameter;
+import org.apache.tiles.autotag.model.TemplateSuite;
+import org.apache.tiles.autotag.model.TemplateSuiteFactory;
+
+import com.thoughtworks.qdox.JavaDocBuilder;
+import com.thoughtworks.qdox.model.Annotation;
+import com.thoughtworks.qdox.model.DocletTag;
+import com.thoughtworks.qdox.model.JavaClass;
+import com.thoughtworks.qdox.model.JavaMethod;
+import com.thoughtworks.qdox.model.JavaParameter;
+import com.thoughtworks.qdox.model.Type;
+
+/**
+ * Creates a template suite using QDox.
+ *
+ * @version $Rev$ $Date$
+ */
+public class QDoxTemplateSuiteFactory implements TemplateSuiteFactory {
+
+    /**
+     * The suffix of parsed classes.
+     */
+    private static final String TEMPLATE_SUFFIX = "Model";
+
+    /**
+     * The Javadoc builder.
+     */
+    private JavaDocBuilder builder;
+
+    /**
+     * The name of the suite.
+     */
+    private String suiteName;
+
+    /**
+     * The documentation of the suite.
+     */
+    private String suiteDocumentation;
+
+    /**
+     * The request class the suite.
+     */
+    private String requestClass;
+
+    /**
+     * Constructor.
+     *
+     * @param sourceFiles All the source files to parse.
+     */
+    public QDoxTemplateSuiteFactory(File... sourceFiles) {
+        builder = new JavaDocBuilder();
+        try {
+            for (File file : sourceFiles) {
+                builder.addSource(file);
+            }
+        } catch (IOException e) {
+            throw new ClassParseException(
+                    "I/O Exception when adding source files", e);
+        }
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param urls All the URLs of source files to parse.
+     */
+    public QDoxTemplateSuiteFactory(URL... urls) {
+        builder = new JavaDocBuilder();
+        try {
+            for (URL url : urls) {
+                builder.addSource(url);
+            }
+        } catch (IOException e) {
+            throw new ClassParseException(
+                    "I/O Exception when adding source files", e);
+        }
+    }
+
+    /**
+     * Sets the suite name to assign to the created suite.
+     *
+     * @param suiteName The suite name.
+     */
+    public void setSuiteName(String suiteName) {
+        this.suiteName = suiteName;
+    }
+
+    /**
+     * Sets the suite documentation to assign to the suite.
+     *
+     * @param suiteDocumentation The suite documentation.
+     */
+    public void setSuiteDocumentation(String suiteDocumentation) {
+        this.suiteDocumentation = suiteDocumentation;
+    }
+
+    /**
+     * Sets the request class used by the suite.
+     *
+     * @param requestClass The request class name.
+     */
+    public void setRequestClass(String requestClass) {
+        this.requestClass = requestClass;
+    }
+
+    @Override
+public org.apache.tiles.autotag.model.TemplateSuite createTemplateSuite() {
+    java.util.List<org.apache.tiles.autotag.model.TemplateClass> classes = new java.util.ArrayList<org.apache.tiles.autotag.model.TemplateClass>();
+    for (com.thoughtworks.qdox.model.JavaClass clazz : builder.getClasses()) {
+        java.lang.String tagClassPrefix = getTagClassPrefix(clazz);
+        {
+            java.lang.String tagName = tagClassPrefix.substring(0, 1).toLowerCase() + tagClassPrefix.substring(1);
+            org.apache.tiles.autotag.model.TemplateMethod executeMethod = null;
+            for (com.thoughtworks.qdox.model.JavaMethod method : clazz.getMethods()) {
+                if (isFeasible(method)) {
+                    executeMethod = createMethod(method);
+                }
+            }
+            {
+                org.apache.tiles.autotag.model.TemplateClass templateClass = new org.apache.tiles.autotag.model.TemplateClass(clazz.getFullyQualifiedName(), tagName, tagClassPrefix, /* NPEX_NULL_EXP */
+                executeMethod);
+                templateClass.setDocumentation(clazz.getComment());
+                classes.add(templateClass);
+            }
+        }
+    }
+    return new org.apache.tiles.autotag.model.TemplateSuite(suiteName, suiteDocumentation, classes);
+}
+
+    /**
+     * Computes the tag class prefix.
+     *
+     * @param clazz The parsed class.
+     * @return The tag class prefix.
+     */
+    private String getTagClassPrefix(JavaClass clazz) {
+        String tagName;
+        String simpleClassName = clazz.getName();
+        if (simpleClassName.endsWith(TEMPLATE_SUFFIX)
+                && simpleClassName.length() > TEMPLATE_SUFFIX.length()) {
+            tagName = simpleClassName.substring(0, 1).toUpperCase()
+                    + simpleClassName.substring(1, simpleClassName.length()
+                            - TEMPLATE_SUFFIX.length());
+        } else {
+            tagName = null;
+        }
+        return tagName;
+    }
+
+    /**
+     * Creates a template method descriptor from a parsed method.
+     *
+     * @param method The parsed method.
+     * @return The template method descriptor.
+     */
+    private TemplateMethod createMethod(JavaMethod method) {
+        List<TemplateParameter> params = new ArrayList<TemplateParameter>();
+        for (JavaParameter parameter : method.getParameters()) {
+            String exportedName = parameter.getName();
+            boolean required = false;
+            String defaultValue = null;
+            Annotation[] annotations = parameter.getAnnotations();
+            if (annotations != null && annotations.length > 0) {
+                boolean found = false;
+                for (int i = 0; i < annotations.length && !found; i++) {
+                    if (Parameter.class.getName().equals(annotations[i].getType().getFullyQualifiedName())) {
+                        found = true;
+                        String candidateName = (String) annotations[i].getNamedParameter("name");
+                        if (candidateName != null && candidateName.length() > 2) {
+                            exportedName = candidateName.substring(1, candidateName.length() - 1);
+                        }
+                        required = "true".equals(annotations[i].getNamedParameter("required"));
+                        candidateName = (String) annotations[i].getNamedParameter("defaultValue");
+                        if (candidateName != null && candidateName.length() > 2) {
+                            defaultValue = candidateName.substring(1, candidateName.length() - 1);
+                        }
+                    }
+                }
+            }
+            String parameterType = parameter.getType()
+                    .getFullyQualifiedName();
+            TemplateParameter templateParameter = new TemplateParameter(
+                    parameter.getName(), exportedName, parameterType, defaultValue, required,
+                    requestClass.equals(parameterType));
+            params.add(templateParameter);
+        }
+        TemplateMethod templateMethod = new TemplateMethod(method.getName(),
+                params);
+        templateMethod.setDocumentation(method.getComment());
+        DocletTag[] tags = method.getTagsByName("param");
+        for (DocletTag tag : tags) {
+            String[] tagParams = tag.getParameters();
+            if (tagParams.length > 0) {
+                TemplateParameter templateParameter = templateMethod
+                        .getParameterByName(tagParams[0]);
+                if (templateParameter != null) {
+                    String tagValue = tag.getValue();
+                    int pos = tagValue.indexOf(" ");
+                    templateParameter.setDocumentation(tagValue.substring(pos)
+                            .trim());
+                }
+            }
+        }
+        return templateMethod;
+    }
+
+    /**
+     * Verifies if the method can be used as an "execute" method.
+     *
+     * @param method The parsed method.
+     * @return <code>true</code> if it is an execute method.
+     */
+    private boolean isFeasible(JavaMethod method) {
+        Type returns = method.getReturns();
+        if ("execute".equals(method.getName()) && returns != null
+                && "void".equals(returns.getFullyQualifiedName())
+                && method.isPublic() && !method.isStatic()
+                && !method.isAbstract() && !method.isConstructor()) {
+            JavaParameter[] params = method.getParameters();
+            if (params.length > 0) {
+                JavaParameter param = params[params.length - 1];
+                if (requestClass.equals(
+                        param.getType().getFullyQualifiedName())) {
+                    return true;
+                }
+            }
+            if (params.length >= 2) {
+                JavaParameter param1 = params[params.length - 2];
+                JavaParameter param2 = params[params.length - 1];
+                if (requestClass.equals(
+                        param1.getType().getFullyQualifiedName())
+                        && ModelBody.class.getName().equals(
+                                param2.getType().getFullyQualifiedName())) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+}
diff --git a/Java/tiles-autotag-QDoxTemplateSuiteFactory_152/metadata.json b/Java/tiles-autotag-QDoxTemplateSuiteFactory_152/metadata.json
new file mode 100644
index 000000000..eb6230d64
--- /dev/null
+++ b/Java/tiles-autotag-QDoxTemplateSuiteFactory_152/metadata.json
@@ -0,0 +1,21 @@
+{
+  "language": "java",
+  "id": "tiles-autotag-QDoxTemplateSuiteFactory_152",
+  "buggyPath": ".",
+  "referencePath": null,
+  "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+  "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+  "categories": [
+    "safety",
+    "npe"
+  ],
+  "npe": {
+    "filepath": "tiles-autotag-core/src/main/java/org/apache/tiles/autotag/core/QDoxTemplateSuiteFactory.java",
+    "line": 153,
+    "npe_method": "createTemplateSuite",
+    "deref_field": "executeMethod",
+    "npe_class": "QDoxTemplateSuiteFactory",
+    "repo": "tiles-autotag",
+    "bug_id": "QDoxTemplateSuiteFactory_152"
+  }
+}
diff --git a/Java/tiles-autotag-QDoxTemplateSuiteFactory_152/npe.json b/Java/tiles-autotag-QDoxTemplateSuiteFactory_152/npe.json
new file mode 100644
index 000000000..ac558fb99
--- /dev/null
+++ b/Java/tiles-autotag-QDoxTemplateSuiteFactory_152/npe.json
@@ -0,0 +1,7 @@
+{
+    "filepath": "tiles-autotag-core/src/main/java/org/apache/tiles/autotag/core/QDoxTemplateSuiteFactory.java",
+    "line": 153,
+    "npe_method": "createTemplateSuite",
+    "deref_field": "executeMethod",
+    "npe_class": "QDoxTemplateSuiteFactory"
+}
\ No newline at end of file
diff --git a/Java/tiles-autotag-StringTool_84/Dockerfile b/Java/tiles-autotag-StringTool_84/Dockerfile
new file mode 100644
index 000000000..fc34ed72c
--- /dev/null
+++ b/Java/tiles-autotag-StringTool_84/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:tiles-autotag
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+    && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+    && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+    && mv /tmp/buggy.java $BUGGY_PATH \
+    && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/tiles-autotag-StringTool_84/buggy.java b/Java/tiles-autotag-StringTool_84/buggy.java
new file mode 100644
index 000000000..d6801041e
--- /dev/null
+++ b/Java/tiles-autotag-StringTool_84/buggy.java
@@ -0,0 +1,149 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.tool;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.tiles.autotag.core.AutotagRuntimeException;
+
+/**
+ * A Velocity tools to manipulate strings.
+ *
+ * @version $Rev$ $Date$
+ */
+public class StringTool {
+
+    /**
+     * Maps a primitive type to its default value as a string.
+     */
+    private Map<String, String> type2default;
+
+    /**
+     * Maps a primitive type to its boxed version.
+     */
+    private Map<String, String> primitive2wrapped;
+
+    /**
+     * Constructor.
+     */
+    public StringTool() {
+        type2default = new HashMap<String, String>();
+        type2default.put("byte", "0");
+        type2default.put("short", "0");
+        type2default.put("int", "0");
+        type2default.put("long", "0L");
+        type2default.put("float", "0.0f");
+        type2default.put("double", "0.0d");
+        type2default.put("char", "'\\u0000'");
+        type2default.put("boolean", "false");
+
+        primitive2wrapped = new HashMap<String, String>();
+        primitive2wrapped.put("byte", Byte.class.getName());
+        primitive2wrapped.put("short", Short.class.getName());
+        primitive2wrapped.put("int", Integer.class.getName());
+        primitive2wrapped.put("long", Long.class.getName());
+        primitive2wrapped.put("float", Float.class.getName());
+        primitive2wrapped.put("double", Double.class.getName());
+        primitive2wrapped.put("char", Character.class.getName());
+        primitive2wrapped.put("boolean", Boolean.class.getName());
+    }
+
+    /**
+     * Creates a list of strings, separating a string when a newline is encountered.
+     *
+     * @param toSplit The string to split.
+     * @return The list of splitted strings.
+     */
+/**
+ * Creates a list of strings, separating a string when a newline is encountered.
+ *
+ * @param toSplit
+ * 		The string to split.
+ * @return The list of splitted strings.
+ */
+public java.util.List<java.lang.String> splitOnNewlines(java.lang.String toSplit) {
+    java.util.List<java.lang.String> retValue = new java.util.ArrayList<java.lang.String>();
+    {
+        java.io.Reader reader = new java.io.StringReader(/* NPEX_NULL_EXP */
+        toSplit);
+        java.io.BufferedReader bufReader = new java.io.BufferedReader(reader);
+        try {
+            java.lang.String line;
+            while ((line = bufReader.readLine()) != null) {
+                retValue.add(line);
+            } 
+        } catch (java.io.IOException e) {
+            throw new org.apache.tiles.autotag.core.AutotagRuntimeException("Cannot read the string completely", e);
+        }
+        return retValue;
+    }
+}
+
+    /**
+     * Creates a string in which the first character is capitalized.
+     *
+     * @param string The string to use.
+     * @return The same string with the first character capitalized.
+     */
+    public String capitalizeFirstLetter(String string) {
+        return string.substring(0, 1).toUpperCase() + string.substring(1);
+    }
+
+    /**
+     * Returns the default value for a type.
+     *
+     * @param type The type.
+     * @param overriddenDefaultValue The default value, as specified by developers.
+     * @return The default value to use.
+     */
+    public String getDefaultValue(String type, String overriddenDefaultValue) {
+        if (overriddenDefaultValue != null) {
+            return overriddenDefaultValue;
+        }
+
+        String retValue = type2default.get(type);
+        if (retValue == null) {
+            retValue = "null";
+        }
+        return retValue;
+    }
+
+    /**
+     * Returns the class to be used to cast an Object.
+     *
+     * @param type The type to use, even a primitive type.
+     * @return The class to be used in casts.
+     */
+    public String getClassToCast(String type) {
+        String retValue = primitive2wrapped.get(type);
+        if (retValue == null) {
+            retValue = type;
+        }
+        return retValue;
+    }
+}
diff --git a/Java/tiles-autotag-StringTool_84/metadata.json b/Java/tiles-autotag-StringTool_84/metadata.json
new file mode 100644
index 000000000..2e3bca1a5
--- /dev/null
+++ b/Java/tiles-autotag-StringTool_84/metadata.json
@@ -0,0 +1,21 @@
+{
+  "language": "java",
+  "id": "tiles-autotag-StringTool_84",
+  "buggyPath": ".",
+  "referencePath": null,
+  "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+  "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+  "categories": [
+    "safety",
+    "npe"
+  ],
+  "npe": {
+    "filepath": "tiles-autotag-core/src/main/java/org/apache/tiles/autotag/tool/StringTool.java",
+    "line": 93,
+    "npe_method": "splitOnNewlines",
+    "deref_field": "toSplit",
+    "npe_class": "StringTool",
+    "repo": "tiles-autotag",
+    "bug_id": "StringTool_84"
+  }
+}
diff --git a/Java/tiles-autotag-StringTool_84/npe.json b/Java/tiles-autotag-StringTool_84/npe.json
new file mode 100644
index 000000000..720d127a0
--- /dev/null
+++ b/Java/tiles-autotag-StringTool_84/npe.json
@@ -0,0 +1,7 @@
+{
+    "filepath": "tiles-autotag-core/src/main/java/org/apache/tiles/autotag/tool/StringTool.java",
+    "line": 93,
+    "npe_method": "splitOnNewlines",
+    "deref_field": "toSplit",
+    "npe_class": "StringTool"
+}
\ No newline at end of file
diff --git a/Java/tiles-autotag-TemplateClass_187/Dockerfile b/Java/tiles-autotag-TemplateClass_187/Dockerfile
new file mode 100644
index 000000000..fc34ed72c
--- /dev/null
+++ b/Java/tiles-autotag-TemplateClass_187/Dockerfile
@@ -0,0 +1,18 @@
+FROM ghcr.io/kupl/starlab-benchmarks/java-base:tiles-autotag
+
+ENV TZ=Asia/Seoul
+
+COPY ./metadata.json .
+COPY ./npe.json .
+COPY ./buggy.java /tmp/buggy.java
+RUN export BUGGY_PATH=$(cat metadata.json | jq -r ".npe.filepath") \
+    && export BUGGY_LINE=$(cat metadata.json | jq -r ".npe.line") \
+    && export BUGGY_MTHD=$(cat metadata.json | jq -r ".npe.npe_method") \
+    && mv /tmp/buggy.java $BUGGY_PATH \
+    && echo "[{\"filepath\": \"$BUGGY_PATH\", \"line\": $BUGGY_LINE, \"method_name\": \"$BUGGY_MTHD\"}]" | jq . > traces.json
+
+RUN git init . && git add -A
+
+RUN $(cat metadata.json | jq -r ".buildCommand")
+
+RUN $(cat metadata.json | jq -r ".testCommand"); if [ $? -eq 0 ]; then exit 1; fi
diff --git a/Java/tiles-autotag-TemplateClass_187/buggy.java b/Java/tiles-autotag-TemplateClass_187/buggy.java
new file mode 100644
index 000000000..69a8d183f
--- /dev/null
+++ b/Java/tiles-autotag-TemplateClass_187/buggy.java
@@ -0,0 +1,203 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.tiles.autotag.model;
+
+import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * It represents a parsed template class.
+ *
+ * @version $Rev$ $Date$
+ */
+public class TemplateClass {
+
+    /**
+     * The class name.
+     */
+    private String name;
+
+    /**
+     * The name of the tag.
+     */
+    private String tagName;
+
+    /**
+     * The prefix of the tag class.
+     */
+    private String tagClassPrefix;
+
+    /**
+     * Documentation about this tag.
+     */
+    private String documentation;
+
+    /**
+     * The method that executes the template class.
+     */
+    private TemplateMethod executeMethod;
+
+    /**
+     * Constructor.
+     *
+     * @param name The name of the template class.
+     */
+    public TemplateClass(String name) {
+        this(name, null, null, null);
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param name The name of the template class.
+     * @param tagName The name of the tag.
+     * @param tagClassPrefix The tag class prefix.
+     * @param executeMethod The method that executes the template class.
+     */
+    public TemplateClass(String name, String tagName, String tagClassPrefix,
+            TemplateMethod executeMethod) {
+        this.name = name;
+        this.tagName = tagName;
+        this.tagClassPrefix = tagClassPrefix;
+        this.executeMethod = executeMethod;
+    }
+
+    /**
+     * The name of the parsed class.
+     *
+     * @return The name of the class.
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Returns the name of the class, without the package part.
+     *
+     * @return The simple class name.
+     */
+    public String getSimpleName() {
+        int pos = name.lastIndexOf('.');
+        if (pos >= 0) {
+            return name.substring(pos + 1);
+        }
+        return name;
+    }
+
+    /**
+     * Returns the tag name.
+     *
+     * @return The tag name.
+     */
+    public String getTagName() {
+        return tagName;
+    }
+
+    /**
+     * Returns the tag class prefix.
+     *
+     * @return The tag class prefix.
+     */
+    public String getTagClassPrefix() {
+        return tagClassPrefix;
+    }
+
+    /**
+     * Returns the documentation for this class.
+     *
+     * @return The documentation.
+     */
+    public String getDocumentation() {
+        return documentation;
+    }
+
+    /**
+     * Sets the documentation for this class.
+     *
+     * @param documentation The documentation.
+     */
+    public void setDocumentation(String documentation) {
+        this.documentation = documentation;
+    }
+
+    /**
+     * Returns the method that execute this class.
+     *
+     * @return The execute method.
+     */
+    public TemplateMethod getExecuteMethod() {
+        return executeMethod;
+    }
+
+    /**
+     * Returns the collection of regular parameters (no request, no body)
+     * of the execute method.
+     *
+     * @return The regular parameters.
+     */
+    public Collection<TemplateParameter> getParameters() {
+        Map<String, TemplateParameter> params = new LinkedHashMap<String, TemplateParameter>();
+        fillRegularParameters(params, executeMethod);
+        return params.values();
+    }
+
+    /**
+     * Indicates that this class needs a tag body.
+     *
+     * @return <code>true</code> if tag body is needed.
+     */
+    public boolean hasBody() {
+        return executeMethod.hasBody();
+    }
+
+    @Override
+    public String toString() {
+        return "TemplateClass [name=" + name + ", tagName=" + tagName
+                + ", tagClassPrefix=" + tagClassPrefix + ", documentation="
+                + documentation + ", executeMethod=" + executeMethod + "]";
+    }
+
+    /**
+     * Creates regular parameters map.
+     *
+     * @param params The map to fill.
+     * @param method The method to analyze.
+     */
+/**
+ * Creates regular parameters map.
+ *
+ * @param params
+ * 		The map to fill.
+ * @param method
+ * 		The method to analyze.
+ */
+private void fillRegularParameters(java.util.Map<java.lang.String, org.apache.tiles.autotag.model.TemplateParameter> params, org.apache.tiles.autotag.model.TemplateMethod method) {
+    {
+        for (org.apache.tiles.autotag.model.TemplateParameter param : /* NPEX_NULL_EXP */
+        method.getParameters()) {
+            if ((!param.isRequest()) && (!param.isBody())) {
+                params.put(param.getName(), param);
+            }
+        }
+    }
+}
+}
diff --git a/Java/tiles-autotag-TemplateClass_187/metadata.json b/Java/tiles-autotag-TemplateClass_187/metadata.json
new file mode 100644
index 000000000..2c1d936f0
--- /dev/null
+++ b/Java/tiles-autotag-TemplateClass_187/metadata.json
@@ -0,0 +1,21 @@
+{
+  "language": "java",
+  "id": "tiles-autotag-TemplateClass_187",
+  "buggyPath": ".",
+  "referencePath": null,
+  "buildCommand": "mvn package -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100 -DskipTests=true -DskipITs=true -Dtest=None -DfailIfNoTests=false",
+  "testCommand": "mvn test -V -B -Denforcer.skip=true -Dcheckstyle.skip=true -Dcobertura.skip=true -Drat.skip=true -Dlicense.skip=true -Dfindbugs.skip=true -Dgpg.skip=true -Dskip.npm=true -Dskip.gulp=true -Dskip.bower=true -Drat.numUnapprovedLicenses=100",
+  "categories": [
+    "safety",
+    "npe"
+  ],
+  "npe": {
+    "filepath": "tiles-autotag-core/src/main/java/org/apache/tiles/autotag/model/TemplateClass.java",
+    "line": 196,
+    "npe_method": "fillRegularParameters",
+    "deref_field": "method",
+    "npe_class": "TemplateClass",
+    "repo": "tiles-autotag",
+    "bug_id": "TemplateClass_187"
+  }
+}
diff --git a/Java/tiles-autotag-TemplateClass_187/npe.json b/Java/tiles-autotag-TemplateClass_187/npe.json
new file mode 100644
index 000000000..f55dc23dd
--- /dev/null
+++ b/Java/tiles-autotag-TemplateClass_187/npe.json
@@ -0,0 +1,7 @@
+{
+    "filepath": "tiles-autotag-core/src/main/java/org/apache/tiles/autotag/model/TemplateClass.java",
+    "line": 196,
+    "npe_method": "fillRegularParameters",
+    "deref_field": "method",
+    "npe_class": "TemplateClass"
+}
\ No newline at end of file